본문 바로가기

React

[React] Redux와 Redux Toolkit 비교 및 구현 방법

 

1. Redux  구현 방법

 

npm i redux react-redux

인스톨 후 사용

 

 

기존 Redux의 특징

  • 액션 타입을 문자열로 직접 정의
  • 액션 생성자를 별도로 만들어야 함
  • 불변성을 직접 관리해야 함 (새로운 객체를 반환)
  • 모든 리듀서 로직을 수동으로 작성
  • 보일러플레이트 코드가 많음
// /store/index.js

import { createStore } from 'redux'

// 초기 상태
const initialState = {
  counter: 0,
  showCounter: true
}

// Action Types
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
export const INCREASE = 'INCREASE'
export const TOGGLE_COUNTER = 'TOGGLE_COUNTER'

// Reducer
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case INCREMENT:
      return {
        ...state,
        counter: state.counter + 1
      }
    case DECREMENT:
      return {
        ...state,
        counter: state.counter - 1
      }
    case INCREASE:
      return {
        ...state,
        counter: state.counter + action.amount
      }
    case TOGGLE_COUNTER:
      return {
        ...state,
        showCounter: !state.showCounter
      }
    default:
      return state
  }
}

const store = createStore(counterReducer)
export default store
import { useSelector, useDispatch } from 'react-redux'
import { INCREMENT, DECREMENT, INCREASE, TOGGLE_COUNTER } from '../store/index'
import classes from './Counter.module.css'

const Counter = () => {
  const dispatch = useDispatch()
  const counter = useSelector(state => state.counter)
  const show = useSelector(state => state.showCounter)

  const incrementHandler = () => {
    dispatch({type: INCREMENT})
  }

  const increaseHandler = () => {
    dispatch({type: INCREASE, amount: 10})
  }

  const decrementHandler = () => {
    dispatch({type: DECREMENT})
  }

  const toggleCounterHandler = () => {
   dispatch({type: TOGGLE_COUNTER})
  }

  return (
    <main className={classes.counter}>
      <h1>Redux Counter</h1>
      {show && <div className={classes.value}>{counter}</div>}
      <div>
        <button onClick={incrementHandler}>Increment</button>
        <button onClick={increaseHandler}>Increase by 10</button>
        <button onClick={decrementHandler}>Decrement</button>
      </div>
      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    </main>
  )
}

export default Counter

 

 

 

 

2. Redux Toolkit 구현 방법

npm i @reduxjs/toolkit

인스톨 후 사용

 

 

Redux Toolkit의 장점

  • createSlice를 통해 액션 생성자와 리듀서를 자동으로 생성
  • Immer 라이브러리가 내장되어 있어 상태를 직접 수정하는 것처럼 작성 가능
  • 보일러플레이트 코드 감소
  • 액션 타입, 액션 생성자가 자동으로 생성됨
  • 더 간결하고 직관적인 코드 작성 가능
// /store/index.js
import {createSlice, configureStore} from '@reduxjs/toolkit'

const initialState = {counter :  0, showCounter: true}

// createSlice action 전달
// 고유 action 식별자를 자동으로 생성
// action 식별자 값을 얻으려면 아래의 counterSlice.actions 사용해야
const counterSlice = createSlice({
  name : 'counter',
  initialState,
  reducers: {
    increment(state){
      state.counter++
    },
    decrement(state){
      state.counter--
    },
    increase(state, action){
      state.counter += action.payload // redux-toolkit 에서는 payload 란 key 값이 default 세팅되있음
    },
    toggleCounter(state){
      state.showCounter = !state.showCounter
    },
  }
})

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

// action 식별자 값을 얻기 
// return 값은 action object 로 나온다 => 직접 action 객체 생성필요 없음
export const counterActions = counterSlice.actions

export default store
import { useSelector, useDispatch } from 'react-redux';

import { counterActions } from '../store/index';
import classes from './Counter.module.css';

const Counter = () => {
  const dispatch = useDispatch()
  const counter = useSelector(state => state.counter)
  const show = useSelector(state => state.showCounter)

  const incrementHandler = () => {
    dispatch(counterActions.increment())
  }
  const increaseHandler = () => {
    dispatch(counterActions.increase(10))
  }
  const decrementHandler = () => {
    dispatch(counterActions.decrement())
  }
  const toggleCounterHandler = () => {
    dispatch(counterActions.toggleCounter())
  };

  return (
    <main className={classes.counter}>
      <h1>Redux Counter</h1>
      {show && <div className={classes.value}>{counter}</div>}
      <div>
        <button onClick={incrementHandler}>Increment</button>
        <button onClick={increaseHandler}>Increment by 10</button>
        <button onClick={decrementHandler}>Decrement</button>
      </div>
      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    </main>
  );
};

export default Counter;

 

3. 구현에 사용하는 주요 메서드 및 기능

 

3-1) createSlice


Redux Toolkit의 핵심 메서드
리듀서 로직과 액션을 한 번에 생성

 

3-2) configureStore
Redux 스토어 생성
여러 리듀서를 하나로 결합

 

3-3) useSelector & useDispatch
useSelector: 스토어의 상태를 가져오는 훅
useDispatch: 액션을 디스패치하는 훅