reducers vs extrareducers
reducers
는 액션함수를 생성함과 동시에 해당 액션함수에 대응하는 역할을 한다.extraReducers
는 사용자가 slice reducer 내에서 액션함수에 접근할 수 있게하지만, extraReducers 내에서 액션함수를 생성하지 않는다는 점이 기존의 reducers 프로퍼티와의 가장 큰 차이점이다.extraReducers
프로퍼티를 사용하는 경우는 이미 다른 곳에서 정의된 액션생성함수를 사용할때인데, 가장 흔한 케이스는 비동기를 위해 createAsyncThunk
를 사용하여 정의된 액션함수를 사용하거나, 다른 slice에서 정의된 액션함수를 사용하는 경우이다.비동기 처리를 위한 createAsyncThunk
createAsyncThunk는
createAction의 비동기 버전을 위해 고안되었다. 액션 타입 문자열과 프로미스를 반환하는 콜백 함수를 인자로 받아서 주어진 액션 타입을 접두어로 사용하는 프로미스 생명 주기 기반의 액션 타입을 생성한다.import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'
const fetchUserById = createAsyncThunk(
'users/fetchByIdStatus',
async (userId, thunkAPI) => {
const response = await userAPI.fetchById(userId)
return response.data
}
)
const usersSlice = createSlice({
name: 'users',
initialState: { entities: [], loading: 'idle' },
reducers: {},
// extraReducers에 케이스 리듀서를 추가하면
// 프로미스의 진행 상태에 따라서 리듀서를 실행할 수 있다.
extraReducers: (builder) => {
builder
.addCase(fetchUserById.pending, (state) => {})
.addCase(fetchUserById.fulfilled, (state, action) => {
state.entities.push(action.payload)
})
.addCase(fetchUserById.rejected, (state) => {})
},
})
// 위에서 fetchUserById, 즉 thunk를 작성해두고
// 앱에서 필요한 시점에 디스패치 하여 사용한다.
// ...
dispatch(fetchUserById(123))
//결론적으로 외부의 액션함수를 사용하여 원하는 slice 내에서 상태처리를 할 수 있게 된다.