npm i @reduxjs/toolkit
Redux Toolkit은 Redux의 공식 개발 도구입니다. Redux의 액션 생성자, 리듀서 자체는 단순한 함수인 데다 미들웨어를 추가할 수 있어서 관련 라이브러리와 도구가 매우 많고 그만큼 개발 방식이 다양합니다. 그래서 사용하다 보면 Redux가 좋긴 한데 액션 및 리듀서를 관리하기 위한 코드의 양이 너무 늘어난다는 불만도 자연스레 생기게 됩니다.
이러한 불편함을 줄이기 위해 Redux에서 직접 개발 도구를 만든것으로 보입니다. 이 도구는 결코 표준이 아니며, 그들이 생각하기에 효율적인 개발 방법이라고 말하고 있지만 직접 API를 살펴보고 코드를 작성해 본 결과 나름 코드의 양을 줄일 수 있는 데다 생각의 전환까지 가져올 수 있었다.
기존에 타입을 설정하고 action을 설정하던 것을 아래와 같이 변경할 수 있습니다.
action.js
const ADD_TODO = "ADD_TODO";
const addToDo = (text) => {
return {
type: ADD_TODO,
text
}
}
action.js
const addToDo = createAction("ADD_TODO");
reducer.js
const toDoListReducer = (state = [], action) => {
switch (action.type) {
case addToDo.type:
// action.text대신 payload를 이용해 전달이 가능합니다.
const newToDoObj = { text: action.payload, id: Date.now() };
return [...state, newToDoObj];
case deleteToDo.type:
// 위의 text와 같이 id를 대신해 payload를 이용해 전달을 할 수 있습니다.
return state.filter(toDo => toDo.id !== action.payload);
default:
return state;
}
}
createReducer()에서는 mutate를 해줘야하는데, 아무것도 return하지 않는filter 같은 경우 새로운 배열을 가지기 때문에 return을 해줘야합니다.
reducer.js
const reducer = createRenderer([], {
[addToDo]: (state, action) => {
state.push(
{ text: action.payload, id: Date.now() }
)
},
[deleteToDo]: (state, action) =>
state.filter(toDo => toDo.id !== action.payload)
});
configureStore함수에 필수로 들어가야하는 요소는 reducer 필드입니다.
그리고 configureStore함수에 middelware 필드를 전달하지 않으면, 기본적으로 제공되는 getDefaultMiddleware API가 있다.
또한, 공식문서에서 applyMiddleware나 devtools가 이미 내장되어있기 때문에 넣지 않길 권장합니다.
const store = configureStore({reducer});
문서에 따르면 action, reducer이 합친 개념입니다. 지금까지는 별도로 관리하고, 타입도 맞춰줘야 해서 불편함이 있었지만 createSlice를 쓰면 코드를 간략하게 줄일 수 있습니다.
createSlice에는 아래와 같이 필요한 요소들이 있습니다.
reducer.js
const toDos = createSlice({
name: "toDoListReducer",
initialState: [],
reducers: {
addToDo: (state, action) => {
state.push({ text: action.payload, id: Date.now() })
},
deleteToDo: (state, action) =>
state.filter(toDo => toDo.id !== action.payload)
},
})
store.js
const store = configureStore({reducer: toDos.reducer});
export const {addToDo, deleteToDo} = toDos.actions;
export default store;