개발/프론트엔드 (JS & React)

[Redux Toolkit] 1 - Redux Toolkit이란? | Redux와 Redux Toolkit 차이

jungwon_ 2022. 11. 11. 00:54

출처: https://redux-toolkit.js.org/

Redux Toolkit이란?

리액트 개발자라면 리덕스에 대해서 들어봤을 것이다.

 

리덕스란 자바스크립트 앱의 state 컨테이너로 1) 앱이 일관되게 동작하도록 하고, 2) 중앙화되어 있으며, 3) state가 언제, 어디서, 왜, 어떻게 바뀌었는지 등을 쉽게 디버깅할 수 있게 해주며, 4) 어떤 UI 계층과도 잘 동작하는 등 플렉시블하다.

 

리액트 프로젝트에서는 React Redux를 사용하는데, 사용법은 리액트 훅의 useReducer를 이해하고 있다면 dispatch, reducer, action, payload 등 비슷하게 동작한다고 생각하면 된다.

(useReducer에 대해 더 알고 싶다면 이 글을 참고)

 

리덕스를 사용하면 state를 관리하기 편하지만 수많은 boilerplate 코드를 작성해야한다는 점에서 불편한 점이 있었다.

 

리덕스 툴킷(Redux Toolkit)이란 이러한 boilerplate 코드가 많은 문제나 리덕스 store를 구성하는 것이 복잡한 문제 등 기존의 리덕스의 문제를 해결하고 유용한 패키지를 디폴트로 포함한 것이라고 생각하면 된다.

 


Redux와 Redux Toolkit의 차이점

그렇다면 Redux Toolkit이 기존 Redux보다 어떤 점이 다르고 편리한지 자세히 알아보기 위해 간단한 Counter 프로젝트(숫자를 더하고 빼는)를 만든다고 가정해보자.

 

기존의 Redux로는 아래와 같이 구현할 수 있다.

import { createStore } from 'redux';

const reducer = (state = { counter: 0 }, action) => {
  switch(action.type) {
    case 'increment':
      return { counter: state.counter + 1 }
    case 'decrement':
      return { counter: state.counter - 1 }
    default:
      return state
  }
}

const store = createStore(reducer);

export default store;
// App.jsx
import { useSelector, useDispatch } from 'react-redux'

function App() {
  const counter = useSelector((state) => state.counter);
  const dispatch = useDispatch();

  const increment = () => {
    dispatch({ type: 'increment' })
  }

  const decrement = () => {
    dispatch({ type: 'decrement' })
  }
  // ...
}

export default App

이런 경우 reducer를 구현할 때마다 type 이름을 명확하게 적도록 해야하고 (혹은 ACTIONS 를 정의해 수동으로 type을 입력하는 것을 방지하는 방법도 있다.), switch문이나 if/else를 사용해야 하는 등 boilerplate 코드가 많다.

 

이제 같은 프로젝트를 Redux toolkit을 사용해서 Redux store를 구성해보자

// store/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  value: 0,
}

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1
    },
    decrement: (state) => {
      state.value -= 1
    }
  },
})

export const { increment, decrement } = counterSlice.actions

export default counterSlice.reducer
// store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './counterSlice'

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
})
// App.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './store/counterSlice'

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

  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          Increment
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          Decrement
        </button>
      </div>
    </div>
  )
}

위 코드를 바탕으로 Redux와 Redux toolkit 차이점을 알아보자.

 

1. Dispatch

가장 크게 주목할 점은 기존 Redux에서는 dispatch를 할 때 아래와 같이 action type과 payload를 전달했던 것과 달리

dispatch({ type: ACTIONS.ADD, payload: { value: 5 }})

Redux toolkit에서는 코드를 더욱 간단하게 구현할 수 있다.

dispatch(add(5))

 

2. Reduc store 구성

configureStore()을 사용해 Redux store를 간단하게 구성할수 있다.

 

3. Reducer

Redux toolkit은 기존의 Redux와는 다르게 reducer에 "mutating" 로직을 작성하는 것을 허용한다. 

 

이는 Immer 라이브러리를 사용하기 때문인데, 실제로 state를 변형하는 것이 아니라 기존 state에 대한 변경을 감지하고 변경 상태를 바탕으로 완전히 새로운 immutable state를 생성한다.

 

4. Action

각 reducer 함수에 따라 Action creator가 자동으로 생성된다. 


React 에서 Redux toolkit 사용해보기

 

기존 React 앱에서 Redux toolkit을 사용하기 위해서 패키지를 설치해줘도 되고

npm install @reduxjs/toolkit react-redux

 

Create React App에서 Redux 예시를 바로 만들어볼 수도 있다.

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

다음 글에서 Redux Toolkit의 API에 대해 더 자세히 알아보자.

 

[Redux toolkit] 2 - Slice, Reducer, Action, Thunk란?

지난 글에서 Redux와 Redux Toolkit의 차이점에 대해 알아보았다. [Redux Toolkit] 1 - Redux Toolkit이란? | Redux와 Redux Toolkit 차이 Redux Toolkit이란? 리액트 개발자라면 리덕스에 대해서 들어봤을 것이다. 리덕스

jwdevv.tistory.com


Reference

- [Redux Toolkit Docs] Quick Start