들어가며😃


교육 프로그램에서 가장 기대되었던 리덕스 수업이 시작되었다. 그런데 왠걸? 너무 빠르잖아? 🤢 슨생님 원래 안그러셨잖아요ㅠ 오늘따라 진도가 왜이렇게 빨리 나가는 느낌인지ㅠ 프로젝트가 다가오면서 강사님 마음도 급해지셨나부다,,,여튼 수업을 바탕으로 반복적으로 예제를 돌려보니 이해가 슬 가기 시작했다. 수업에서는 Redux-Toolkit에 대한 개념을 알아보았고 그 개념들을 오늘 포스팅에 정리해보려 한다.



Redux-Toolkit 이란?


우선 Redux-Toolkit(RTK)이란, Redux를 더 쉽게, 간단하게 작성할 수 있도록 도와주는 라이브러리이다. Redux의 복잡한 설정과 보일러 코드를 간소화 시키는 등의 많은 이점을 가지고 있어 공식문서에서도 Redux-Toolkit 사용과 전환을 권장하고 있다. 오늘은 Redux-Toolkit에서 지원하는 기능 중 createSlice()를 중점으로 리턱스 툴킷 사용법을 알아보자. 아래의 예제는 이전 포스팅에서 계속 해왔던 counter 를 주제로 다루며, 아래의 명령어로 환경을 세팅해주었다.

npm install react-redux
npm install @reduxjs/toolkit
npm install --save redux-logger



createSlice()


src 폴더 내부에 store 혹은 redux 파일을 생성해주고 그 안에 counterStore.js 파일을 만들어주었다.
createSlice() 함수를 통해 초기 상태, 리듀서와 액션을 한번에 정의할 수 있다. 이전에 액션을 따로 정의해주고, 그에 해당하는 리듀서 함수를 정의하고, 초기값을 어떻게 저떻게 변경하고.. 하는 부분에서 아주 간편해진 모습이다.

import { createSlice } from "@reduxjs/toolkit";
const initialState = { value: 0 };

export const countSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment(state) {
      //   return { value: state.value + 1 };
      state.value += 1;
    },
    decrement(state) {
      //   return { value: state.value - 1 };
      state.value -= 1;
    },
    reset() {
      //   return { value: initialState.value };
      state.value = initialState.value;
    },
  },
});

export const { increment, decrement, reset } = countSlice.actions;
export default countSlice.reducer;

코드를 뜯어보자.

  1. name : 슬라이스 이름이며 다른 액션들과 이름 중복을 피하기 위해 고유의 값을 가져야한다.
  2. initialState : 미리 생성한 초기값을 할당한다.
  3. reducers : 각각의 action과 state의 변화를 정의한다. 각 이름은 dispatch로 부르는 액션함수의 이름이다. dispatch를 통해 전달한 값은 action.payload를 통해 받을 수 있다.
    ++ state의 변화에서 편리한게 주석처럼 return하지 않고도 불변성을 유지하며 업데이트할 수 있다.
  4. action 들과 reducer를 export 해준다.



store


counter.js 파일이 있는 store 폴더에 store.js 파일을 생성해주었다. configureStore() 메소드를 통해 store를 생성한다. 그리고 위에서 내보낸 reducer 를 store에 등록시켜준다. 아래의 예제에서는 counter 라는 이름으로 등록해주었는데 이는 다음 counter.js 파일에서 state.counter.value 로 값을 불러올 때 사용된다.

import { configureStore } from "@reduxjs/toolkit";
import countReducer from "./countStore";

const store = configureStore({
  reducer: {
    counter: countReducer,
    // 아래 다른 리듀서
  },
});

export default store;



Provider


위에서 작성한 store를 전역으로 내려주기 위해 App을 Provider로 감싸준다. 이제 어떤 컴포넌트에서도 countSlice 를 쓸 수 있다!😀

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

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



useSelector, useDispatch


이제 counter.js 라는 페이지 파일에서 상태값을 불러오고 액션에 따른 함수를 할당시켜보자. 우선 store 에 저장된 값을 불러오려면 useSelector()를 통해 아래와 같이 불러와야한다.

const count = useSelector((state) => state.counter.value);
// counter : 위에서 store에 저장된 reducer의 이름


그리고 useDispatch()를 사용하여 상태를 변경할 값을 전달해준다.

const dispatch = useDispatch();
<button onClick={() => dispatch(increment())}>+</button>;


counter.js 전체코드

import { useDispatch, useSelector } from "react-redux";
import { decrement, increment, reset } from "../redux/countStore";

export default function ReduxCount() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <div>카운터 : {count}</div>
      <div>
        <button onClick={() => dispatch(increment())}>+</button>
        <button onClick={() => dispatch(decrement())}>-</button>
        <button onClick={() => dispatch(reset())}>reset</button>
      </div>
    </div>
  );
}



이렇게 해주면 redux-toolkit으로 간단한 카운터 앱 만들기는 끝이다! 결과는 아래와 같다.

카운터 앱






허허허. 위의 로직은 redux를 사용해본 경험이 있다면 아주 쉽게 이해하겠지만 사실 나는 redux를 사용해본적이 없어서 한번에 이해하기 어려웠다. 직접 손으로 쳐보고, 예제를 두어개 풀어보고 나서야 아하? 싶었다. 이해가 되니 꽤 재미졌다. 생각보다 재밌고 다양한 리액트의 상태관리 세계..빠져든다 빠져들어 😵‍💫😵‍💫😵‍💫