리덕스 연습을 위해 간단한 투두리스트를 만들어볼거다.
그전에 store, reducer 등 기초 세팅을 해보자!
createStore
를 사용하는 걸로 알고 있었는데, 공식문서에서 보니 Toolkit 을 사용하라고 나와있었다.아예 사용할 수 없는것이 아니다. 사용은 할 수 있지만, 툴킷을 사용하는 것을 권장하고 있었다.
이에 툴킷의 공식문서를 보면서 튜토리얼 따라하면 된다.
튜토리얼 보면서 따라하는데 recoil 보고싶었다...
import { configureStore } from "@reduxjs/toolkit";
export default configureStore({
reducer: {},
});
Provider
에 넣어준다.import ReactDOM from "react-dom/client";
import App from "./App";
import store from "../src/store";
import { Provider } from "react-redux";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<Provider store={store}>
<App />
</Provider>
);
createAction
을 사용하면 훨씬 간단하게 만들 수 있다.addToDo
,deleteToDo
를 만들었다.// -store.ts
const addToDo = createAction<string>("ADD");
const deleteToDo = createAction<string>("DELETE");
switch
문을 사용하여 모든 케이스 별로 하나씩 적어줘야했다고 한다....state
를 적어주었어야했는데... // - 기존 Reducer
const toDoreducer = (state = [], action: any) => {
switch (action.type) {
case addTodo.type:
return [{ text: action.payload, id: Date.now(), ...state }];
case deleteTodo.type:
return state.filter(toDo => toDo !== action.payload);
default:
return state;
}
};
createReducer
로 쉽게 작성할 수 있다.state
, 두 번째 매개변수로는 builder callback
을 전달한다.builder callback
을 사용하면 리듀서의 새로운 상태를 반환하는 로직을 작성할 수 있다.// - 변경 후 Reducer
interface ToDo {
text: string;
id: number;
}
export const reducer = createReducer<ToDo[]>([], builder => {
builder
.addCase(addToDo, (state, action) => {
state.push({ text: action.payload, id: Date.now() });
})
.addCase(deleteToDo, (state, action) => {
return state.filter(toDo => toDo.id !== Number(action.payload));
});
});
addCase
의 첫 번째 매개변수는 액션 생성자 함수를 전달,createSlice
는 액션 생성자 함수와 리듀서 함수를 자동으로 생성한다.name
, 두 번째 인자로 초기 상태 객체(initialState
), 세 번째 인자로는 액션 생성자 함수와 리듀서 함수를 정의하는 객체 reducer
를 전달한다.// 최종 store.ts 코드!
interface ToDo {
text: string;
id: number;
}
interface ToDoState extends Array<ToDo> {}
const initialState: ToDoState = [];
const toDos = createSlice({
name: "toDosReducer",
initialState,
reducers: {
add: (state, action) => {
↑ 이게 action
state.push({ text: action.payload, id: Date.now() });
},
remove: (state, action) => {
return state.filter(toDo => toDo.id !== Number(action.payload));
},
},
});
export const { add, remove } = toDos.actions;
export const store = configureStore({ reducer: toDos.reducer });