[포스코x코딩온] 웹개발자 풀스택 과정 9기 12주차 회고록 - Redux toolkit

🤔 Redux Toolkit 이란?

Redux Toolkit은 Redux를 더 사용하기 쉽게 사용하기 위해 만들어진 React의 도구이다. Redux의 문제점을 해결하기 위해 개발된 도구라고 생각하면 된다.

 

잠깐! Redux란??

props 없이 state(상태)를 공유할 수 있게 도와주는 라이브러리입니다.
Redux가 설치되어 있다면 js 파일 하나에 state들을 보관할 수 있습니다.

그러면 이런 Redux를 두고 Toolkit을 사용하는 걸까?

 

Redux 단점

  • Redux 스토어 구성이 너무 복잡하다.
  • Redux에서 유용한 작업을 수행하려면 많은 패키지를 추가해야 한다.
  • Redux에는 너무 많은 상용구 코드가 필요하다.

이러한 문제점을 해결해준다니 안 쓸 이유가 없다. 실제로 써봤는데 코드량도 줄어든 체감을 느낄 수 있었다.

 

📙Redux Toolkit 사용법 배우기

 

● Redux Toolkit 설치하기

npm install redux react-redux @reduxjs/toolkit

사용하기전 redux와 redux toolkit을 둘다 설치해준다. 

 

● Redux Toolkit 문법

 

● 최상위 index.js 파일

import React from 'react';
import ReactDom from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux';
import store from './store';

const root = ReactDom.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

최상위 index 파일에는 Provider를 불러와 App 컴포넌트를 감싸준다. Provider의 store에는 여러 state가 담겨있는 reducer  객체가 있다. 그럼 store폴더는 어떻게 생겼을까?

 

● 폴더 구조

먼저 폴더 구조를 보면 리듀서들이 담겨있는 store라는 폴더가 있다. 여기엔 여러 리듀서들이 있고 그 리듀서들을 한번에 모아둔 index.js 파일이 있다.  

 

● store/index.js 파일 (store 파일)

여긴엔 위에도 말했다시피 모든 리듀서들을 담고 있다. 

import { configureStore } from '@reduxjs/toolkit';
import counterSlice from './counter';
import loginSlice from './login';

// 스토어 생성
const store = configureStore({
  reducer: { count: counterSlice, login: loginSlice },
});


export default store;

그럼 counterSlice는 어떻게 생겼는지 확인해 보자

 

● store/counter.js 파일(리듀서 파일)

import { createSlice } from '@reduxjs/toolkit';

const initCount = {
  counter: 10,
};

// createSlice() : 리듀서와 액션을 함께 생성하는 함수
const counterSlice = createSlice({
  name: 'counter',
  initialState: initCount,
  reducers: {
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    },
    calc(state, action) {
      console.log(action.payload.plus);
      const { plus, minus } = action.payload;
      state.counter = state.counter + plus;
    },
  },
});

// 리듀서만 사용할 것이기 때문
export default counterSlice.reducer;
export const counterAction = counterSlice.actions;

counterSlice는 초기값이 10이고 dispatch로 increament,decrement,calc가 왔을 때 실행되는 리듀서다.

createSlice에는 총 3개의 인자값이 오는데 이름, 초기값, 리듀서가 온다. 리듀서와 액션을 함께 생성하기 때문에 확실히 코드량이 줄어든 모습을 볼 수 있다. 

 

● Counter.js 파일(컴포넌트 파일)

import { useDispatch, useSelector } from 'react-redux';
import { counterAction } from './store/counter';

export default function Counter() {
  const counter = useSelector((state) => state.count.counter);
  console.log(counter);
  const dispatch = useDispatch();

  const add = () => {
    dispatch(counterAction.increment());
  };
  const minus = () => {
    dispatch(counterAction.decrement());
  };
  const calc = () => {
    dispatch(counterAction.calc({ plus: 5, minus: 1 }));
  };
  return (
    <div>
      <h2>{counter}</h2>
      <button onClick={add}>ADD</button>
      <button onClick={minus}>MINUS</button>
      <button onClick={calc}>CALC</button>
    </div>
  );
}

counter 변수에는 counterSlice에서 만든 초기값을 넣어준다. 여기서 state.conut를 하는 이유는 store/index.js 파일에서 counterSlice를 count로 할당해줬기 때문이다. 

그럼 state.count.counter에서 counter는 store/count.js파일에서 초기값을 counter:1로 지정해줬기 때문에 쓰였다. 

 

useDispatch훅을 가져와서 dispatch에 action값을 할당해준다. 

CALC버튼을 누르면 2개의 값이 넘어간다. 

만약 2개의 값을 넘겨주고 싶다면 객체형태로 변화해서 보내줄 수 있다. 

 

이러면 reducer에서 payload로 받을 수 있다.

action.payload를 콘솔로 찍어보면 

 

 

plus 액션을 취하고 싶다 -> state.counter = state.counter + action.payload.plus;

minus 액션을 취하고 싶다 -> state.counter = state.counter + action.payload.minus;

 

 

payload는 값을 여러개 보낼때만 사용하면 될 거 같다.