설정, 미들웨어 설치, 반복되는 코드 등 할일이 너무 많다. 또, 불변성 유지의 어려움 등을 도와주는 모델이다.
npm install @reduxjs/toolkit
configureStore
import { createSlice, configureStore } from '@reduxjs/toolkit';
// counterSlice.js
const counterSlice = createSlice({
name: 'counterSlice',
initialState: { value:0 },
reducers: {
up: (state, action) => {
state.value = state.value + action.payload;
}
}
});
export default counterSlice;
export const {up} = counterSlice.actions;
// store.js
// 작은 slice들을 모아서 store로 만들 때, configureStore
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
});
// action을 직접 만들지 않고 자동으로 만들어주는 actionCreator
dispatch(up());
<button onClick={()=>{
dispatch(asyncUpFetch());
}}>+ async thunk </button>
//
const asyncUpFetch = createAsyncThunk(
'counterSlice/asyncFetch',
async () => {
const res = await fetch();
const data = await res.json();
return data.value;
}
)
createAsyncThunk는 비동기 작업을 처리하는 action을 만들어준다.
asyncUpFetch는 actionCreator이기 때문에 첫번째 파라미터로 type이 필요하다.
action이 실행되었을 때, 처리되어야하는 작업을 두번째 parameter에 함수로 전달한다.
// counterSlice.js
const counterSlice = createSlice({
name: 'counterSlice',
initialState: {
value:0,
status: 'Welcome'
},
// 동기 작업의 경우,
reducers: {
up: (state, action) => {
state.value = state.value + action.payload;
}
},
// 비동기 작업의 경우,
extraReducers: (builder) => {
builder.addCase(asyncUpFetch.pending, (state, action) => {
state.status = 'Loading';
})
builder.addCase(asyncUpFetch.fulfilled, (state, action) => {
state.value = state.value + action.payload;
state.status = 'complete';
})
builder.addCase(asyncUpFetch.rejected, (state, action) => {
state.status = 'fail';
})
}
});
action creator는 아래와 같이 3가지 상태를 갖고 각각의 상태일 때의 reducer를 정리해주어야 한다.