리덕스 툴킷
리덕스 툴킷은 우리가 이전에 배운 리덕스를 개량한 것으로 생각하시면 됩니다.
리덕스를 사용하기 위해 작성했던 duck 패턴의 요소들이 전체적인 코드의 양을 늘린다는 개발자들의 불만이 발생하기 시작했고, 리덕스 팀에서는 이것을 수용하여 코드는 더 적게, 그리고 리덕스를 더 편하게 쓰기 위한 기능들을 흡수해서 만든 것이 리덕스툴킷 입니다. 줄여서 RTK 라고도 합니다.
1. 툴킷 설치
CRA를 통해 새로운 프로젝트틀 생성하고 yarn을 통해 아래 패키지를 설치합니다.
yarn add react-redux @reduxjs/toolkit
2. 툴킷비사용 프로그램과 코드 비교
아래 보이는 코드는 일반 리덕스의 counter 프로그램 모듈입니다. Action Value, Action Creator를 별도로 생성해줘야 했습니다. 그리고 리듀서에서 값을 어떻게 변화시킬 지 만들어줬어야 했죠. 이 부분은 여러분들이 모두 익숙하실 것으로 생각됩니다.
// Action Value
const ADD_NUMBER = "ADD_NUMBER";
const MINUS_NUMBER = "MINUS_NUMBER";
// Action Creator
export const addNumber = (payload) => {
return {
type: ADD_NUMBER,
payload,
};
};
export const minusNumber = (payload) => {
return {
type: MINUS_NUMBER,
payload,
};
};
// Initial State
const initialState = {
number: 0,
};
// Reducer
const counter = (state = initialState, action) => {
switch (action.type) {
case ADD_NUMBER:
return {
number: state.number + action.payload,
};
// [퀴즈 답]
case MINUS_NUMBER:
return {
number: state.number - action.payload,
};
default:
return state;
}
};
// export default reducer
export default counter;
아래 코드가 리덕스 툴킷을 사용해서 만든 counter 프로그램 모듈입니다. 일반 리덕스를 사용했을보다 확실히 코드의 양이 줄었습니다.
한번 자세히 살펴보면 큰 차이점은 Action Value와 Action Creator를 이제 직접 생성해주지 않고, Action Value, Action Creator, Reducer가 하나로 합쳐졌다는 점 입니다.
이제 우리는 Slice 라는 API를 사용합니다. 이 슬라이스를 사용하면, 저 3개를 각각 만들어줄 필요 없이 한번에 3개가 모두 만들어집니다.
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
number: 0,
};
export const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
addNumber: (state, action) => {
state.number = state.number + action.payload;
},
minusNumber: (state, action) => {
state.number = state.number - action.payload;
},
},
});
export const { addNumber, minusNumber } = counterSlice.actions;
export default counterSlice.reducer;
슬라이스만 자세히 보겠습니다. 슬라이스는 createSlice 라는 API를 통해 만들 수 있습니다. 그리고 그 인자로 설정정보를 객체로 받는데, 그 안에 우리가 필수로 작성해줘야 하는 값은 name, initialState, reducer가 있습니다.
const counterSlice = createSlice({
name: '', // 이 모듈의 이름
initialState : {}, // 이 모듈의 초기상태 값
reducers : {}, // 이 모듈의 Reducer 로직
})
신기한 것은 위의 counterSlice 리듀서 객체 안에서 만들어주는 함수가 리듀서의 로직이 되면서도 동시에 Action Creator가 된다는 점입니다. 그리고 Action Value 까지 함수의 이름을 따서 자동으로 만들어집니다. 그래서 우리는 Reducer만 만들어주면 됩니다.
// 리듀서 counterSlice
export const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
// 리듀서 안에 만든 함수 자체가 리듀서 로직이자, Action creator가 된다 ✨
addNumber: (state, action) => {
state.number = state.number + action.payload;
},
minusNumber: (state, action) => {
state.number = state.number - action.payload;
},
},
});
그리고 우리가 일반 리덕스에서 export를 통해서 각각의 Action Creator를 내보내주었던 것을 아래 코드를 작성하면 똑같이 내보낼 수 있습니다. 그래서 리듀서에 로직을 추가할 때마다 함수를 추가해서 내보내주면 됩니다.
export const { addNumber, minusNumber } = counterSlice.actions;
export default counterSlice.reducer;
3. 스토어 비교
import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter";
const rootReducer = combineReducers({
counter,
});
const store = createStore(rootReducer);
export default store;
configStore에서도 아래와 같이 작성하면 되며, 크게 달라지는 점은 없습니다.
import { configureStore } from "@reduxjs/toolkit";
import counter from "../modules/counterSlice";
const store = configureStore({
reducer: {
counter,
},
});
export default store;
그리고 이렇게 생성한 store를 export default 해서 최상위의 index.js Provider에 주입해주는 것은 전혀 바뀐게 없습니다.
import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import App from "./App";
import store from "./redux/config/configStore";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
);
// 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();
출처 - 스파르타코딩클럽(항해99과정):https://hanghae99.spartacodingclub.kr/