redux에서 비동기함수 처리는 [redux-thunk](https://github.com/reduxjs/redux-thunk)라는 별도의 미들웨어를 통해야 한다.
반면 rtk은 비동기함수 처리를 위해 createAsyncThunk 함수를 내장하고 있다.
Thunk란?
https://moonscode.tistory.com/249
createAsyncThunk란?
redux-thunk는 단순히 내 코드블럭을 wrapping하여 실행을 지연시키는 함수이다.
createAsyncThunk는 이 redux-thunk 기능을 구조화한 API이다.
지연단계를 pending, fulfilled, rejected 3단계로 구조화하여 제공하고 다양한 옵션으로 그 과정을 세밀히 조정할 수 있다.
pending | thunk 실행중 |
fulfilled | thunk 완료 |
rejected | thunk 실패 |
일차적으로 반환받는 결과는 thunk의 단계이다.
thunk의 단계가 fulfilled이 되면 비로소 thunk의 결과값을 받을 수 있다.
createAsyncThunk 선언.
createAsyncThunk는 createAction을 통해서 pending, fulfilled 그리고 rejected 세 가지 상태를 반환.
(createAsyncThunk에서 반환하는 단계도 redux에서는 action으로 정의)
// fetchUserById.pending
// fetchUserById.fulfilled
// fetchUserById.rejected
const fetchUserById = createAsyncThunk(
// param1. type - thunk를 식별하기 위한 action type
// 'users/fetchByIdStatus/pending'
// 'users/fetchByIdStatus/fulfilled'
// 'users/fetchByIdStatus/rejected'
'users/fetchByIdStatus',
// param2. payloadCreator - (비동기) 로직을 반환하는 함수
// (arg, thunkAPI) => {}
// arg - dispatch할 때 전달된 매개변수
// thunkAPI = { dispatch, getState, extra, requestId, signal, rejectWithValue, fulfillWithValue } - redux에서 thunk 함수로 전달하는 매개변수와 옵션
async (userId: number, thunkAPI) => {
const response = await userAPI.fetchById(userId)
return response.data
}
// param3. options
// { condition, dispatchConditionRejection, idGenerator, serializeError, getPendingMeta }
)
// Then, handle actions in your reducers:
const usersSlice = createSlice({
name: 'users',
initialState,
reducers: {
// standard reducer logic, with auto-generated action types per reducer
},
extraReducers: (builder) => {
// Add reducers for additional action types here, and handle loading state as needed
builder.addCase(fetchUserById.fulfilled, (state, action) => {
// Add user to the state array
state.entities.push(action.payload)
})
},
})
createAsyncThunk Result.
createAsyncThunk는 Promise를 반환.
비동기의 결과값(Thunk 선언. 예제에서 response.data 값)에 접근하고 싶다면?
extraReducers에서 fulfilled 단계를 정의하면 되지만, 클릭이벤트와 같이 redux의 context 밖에서 처리하려면 unwrap 속성이 필요
without unwrap | unwrap |
반환된 Promise를 직접 사용하여 비동기 작업을 처리. | 반환된 Promise에서 비동기 작업의 결과값을 추출. |
// thunk는 기본적으로 promise(함수의 단계를 반환하는 promise)를 반환
const onClick = () => {
dispatch(fetchUserById(userId)).then(() => {
// do additional work
})
}
// unwrap
// createAsyncThunk가 반환한 Promise에는 fulfilled, rejected 상태를 처리할 수 있는 unwrap 속성을 가진다.
const onClick = () => {
dispatch(fetchUserById(userId))
.unwrap()
.then((originalPromiseResult) => {
// handle result here
})
.catch((rejectedValueOrSerializedError) => {
// handle error here
})
}
// unwrapResult
const onClick = () => {
dispatch(fetchUserById(userId))
.then(unwrapResult)
.then((originalPromiseResult) => {
// handle result here
})
.catch((rejectedValueOrSerializedError) => {
// handle result here
})
}
'FrontEnd > Redux' 카테고리의 다른 글
[Redux] redux-thunk (0) | 2023.08.14 |
---|---|
[Redux] redux-orm (0) | 2023.08.10 |
[Redux] with RTK (0) | 2023.08.01 |