📌 Redux Toolkit
Redux Toolkit이란? 리덕스를 사용하기 위해 작성했던 ducks 패턴의 요소들이 전체적인 코드의 양을 늘린다는 개발자들의 불만이 발생했고, 리덕스 팀에서 이것을 수용하여 코드는 더 적게, 그리고 리덕스를 더 편하게 쓰기 위한 기능들을 흡수해서 만든 것이다.
1-1) 설치하기
yarn add @reduxjs/toolkit
1-2) confingStore 구성하기
import { configureStore } from "@reduxjs/toolkit";
import counter from "../modules/counter";
// configureStore 사용하기
const store = configureStore({
// Reducer
reducer: {
counter: counter,
},
});
export default store;
1-3) index.js 구성하기 (기존 리덕스와 동일)
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "./redux/config/configStore";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
1-4) modules > counter.js 구성하기
// (1) createSlice import 하기
import { createSlice } from "@reduxjs/toolkit";
// (2) Initial State 설정하기
const initialState = {
number: 0,
};
// (3) createSlice API 사용하기
// createSlice는 Action Value, Action Creator, Reducer가 하나로 합쳐진 것
// createSlice는 name, initialState, reducers를 인자로 가지는 API
// createSlice는 reducer도 만들어내지만 action creator도 동시에 만들어냄!
const counterSlice = createSlice({
name: "counter",
// 설정 해놓은 initialState 가져오기
initialState,
// 여러 개의 리듀서가 필요함으로 객체 형태로 만들어줌
// value는 state와 action을 인자로 가지는 함수로!
reducers: {
addNumber: (state, action) => {
// 여기에 state를 변경하는 로직 작성
state.number = state.number + action.payload;
},
minusNumber: (state, action) => {
// 여기에 state를 변경하는 로직 작성
state.number = state.number - action.payload;
},
},
});
// (4) action creator와 reducer export 해주기
// action creator는 컴포넌트에서 사용하기 위해 구조분해할당하여 export 해줌!
// counterSlice.actions의 action은 addNumber와 minusNumber를 가지고 있는
// 객체(리듀서이자 액션 크리에이터)를 의미
export const { addNumber, minusNumber } = counterSlice.actions;
// reducer는 configStore에 등록하기 위해 export default 해줌!
export default counterSlice.reducer;
2-1) Redux Toolkit 특징 : immer
import { createSlice } from "@reduxjs/toolkit";
import { v4 as uuidv4 } from "uuid";
const initialState = [
{
id: uuidv4(),
title: "리액트 공부하기",
contents: "빨리빨리 암기하기",
isDone: false,
},
{
id: uuidv4(),
title: "스프링 공부하기",
contents: "인강 열심히 들어보기!!",
isDone: true,
},
{
id: uuidv4(),
title: "데이트",
contents: "홍대입구역에서 3시까지",
isDone: false,
},
];
const todosSlice = createSlice({
name: "todos",
initialState,
reducers: {
addTodo: (state, action) => {
// 이전에는 불변성을 유지시키기 위해 아래와 같은 스프레드 문법? 새로운 객체 리턴? 방법을 사용했었음!
// return [...state, action.payload];
// push의 경우 불변성을 유지해주지 않는 API이기 때문에
// state가 변경되었는지 아닌지 리액트가 알아차릴 수 없음! 따라서 사용 X
// 그러나 redux toolkit은 immer라는 기능이 내장되어 있어서
// 아래와 같이 작성 가능 함!
// immer란? 불변성을 유지시키기 위해 해야 하는 작업들을 간편하게 해줌!
state.push(action.payload)
},
removeTodo: (state, action) => {
return state.filter((item) => item.id !== action.payload);
},
switchTodo: (state, action) => {
return state.map((item) => {
if (item.id === action.payload) {
return { ...item, isDone: !item.isDone };
} else {
return item;
}
});
},
},
});
export const { addTodo, removeTodo, switchTodo } = todosSlice.actions;
export default todosSlice.reducer;
2-2) Redux Toolkit 특징 : devtools