redux-toolkit(리덕스 툴킷) 사용법

Jungmin Lee·2022년 7월 19일
12

redux-toolkit

목록 보기
1/1

요즘 핫한 react-query와 swr에 영향을 받아서 인지 redux보다 사용하기 편한 redux-toolkit을 만들었습니다. redux-toolkit 기본 사용법을 익히고자 생활코딩 redux-toolkit 강의를 보면서 학습하였습니다.

1. redux와 비교하여 redux-toolkit 의 장점에 대해 알아봅시다.

  1. 초기 설정이 간편해졌습니다. 기존 redux는 리덕스 스토어를 구성하는 것은 너무 복잡하였지만, 툴킷에서는 좀 더 간편화되었습니다.
  2. 더이상 다양한 패키지들를 설치 하지 않아도 됩니다. 리덕스를 사용하면 redux devtool, immer, thunk 등 여러가지 라이브러리를 추가적으로 설치해야 하지만, redux-toolkit 내부에 이미 설치가 되어 있기에 굳이 설치 할 필요가 없습니다.
  3. 반복되는 코드가 너무 많아 코드가 복잡해지고 실수를 많이 유발했지만 이러한 부분이 많이 개선되었습니다.
  4. 툴킷에서는 더이상 불변성을 신경쓰지 않아도 됩니다.

학습을 위해 리덕스를 활용해 카운팅 프로젝트를 만들었으며 파일 하나하나씩 보여드리면서 설명을 하겠습니다.

2. redux-toolkit 설치 방법입니다.

1. react-create-app으로 바로 설치하고 싶을 때

Redux + Plain JS template

npx create-react-app my-app --template redux

Redux + TypeScript template

npx create-react-app my-app --template redux-typescript

2. 이미 앱이 존재하여 redux-toolkit만 설치할 때

NPM

npm install @reduxjs/toolkit

Yarn

yarn add @reduxjs/toolkit

3. 카운터 프로젝트 내부 파일

1. app.js

import { Provider } from "react-redux";
import Counter from "./components/Counter";
import store from "./store";

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

export default App;

이부분은 기본 리덕스와 비슷한데 Provider로 store를 저장해줍니다.
store는 저장소라고 생각하시면 이해하기 쉽습니다.
그 저장소 내부에는 여러 개의 slice들로 이루어져 있습니다.

2. store/index.tsx

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

const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;

먼저 store에 대해 설명드리자면 configureStore를 통해 store를 만들어주었습니다.
configureStore의 역할은 여러 개의 slice들을 모아주는 역할이라고 보면 이해하기 쉽습니다.
내부 reducer에 s를 붙이지 않게 주의합니다.
타입스크립트를 사용 중이기에 RootState, AppDispatch를 만들어주었습니다.

3. store/counterSlice.tsx

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

type InitialState = {
  id: number;
  value: number;
};

const initialState: InitialState = {
  id: 1,
  value: 0,
};
const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    up: (state, action) => {
      state.value = state.value + action.payload;
    },
    down: (state, action) => {
      state.value = state.value - action.payload;
    },
    init: (state, action) => {
      state.value = 0;
    },
  },
});

export default counterSlice;
export const { up, down, init } = counterSlice.actions;

createSlice로 Slice를 만듭니다. createSlice는 객체를 인자로 받고 객체에는 name, initialState, reducers를 필수 요소입니다.
name: 이름, initialState: 초기 상태, reducers: 메소드(함수)로 이루어져 있습니다.
counterSlice는 store/index.tsx (저장소)에서 사용도 하지만, dispatch 할때도 사용해야 하기에 export를 해줍니다.
dispatch에서 메소드에 접근하기 쉽게 구조분해 할당을 해줍니다.

4. components/Counter.tsx

import { useSelector, useDispatch } from "react-redux";
import { RootState } from "../store";
import { down, init, up } from "../store/counterSlice";

function Counter() {
  const dispach = useDispatch();
  const count = useSelector((state: RootState) => {
    return state.counter.value;
  });
  const addNumber = () => {
    dispach(up(2));
  };
  const minusNumber = () => {
    dispach(down(2));
  };
  const initNumber = () => {
    dispach(init(""));
  };

  return (
    <div>
      <div>{count}</div>
      <button onClick={addNumber}>+</button>
      <button onClick={minusNumber}>-</button>
      <button onClick={initNumber}>초기화</button>
    </div>
  );
}

export default Counter;

해당 컴포넌트에는count의 값을 나타내기 위해 redux state에서 데이터를 받아와 보여주고 총 3가지 버튼으로 더하기,빼기,초기화 기능이 있습니다.
useSelector 는 store의 state를 인자를 받아옵니다 (큰 저장소).
즉, console.log(state)로 찍어보면 내부에 counter(counterSlice)를 가지고 있는 걸 알 수있습니다. 만약 slice가 더 있다면 여러 개가 나타겠죠?
우리는 counter가 가지고 있는 value값에 접근하여 이를 화면에 출력합니다.타입스크립트를 사용하시는 분은 state 타입을 RootState로 설정해주면 됩니다.
그러면 counterSlice/initialState타입으로 설정됩니다.RootState와 AppDispatch는 주로 hook로 설정해서 사용하기도 합니다.

다음으로 useDispach에 대해 설명드리자면, dispach를 통해 counterSlice의 내부 메소드에 접근할 수 있습니다.
우리는 메소드를 구조분해할당으로 빼뒀기 때문에 이런 식으로 dispach(up(2)); 바로 사용이 가능합니다.
counterSlice의 up메소드에서 console.log(action)을 찍어보면 인자 값인 2가 action.payload로 있는 걸 확인할 수 있습니다.

profile
Front-end developer who never gives up.

0개의 댓글