[TIL] Redux ToolKit (RTK)

·2023년 11월 28일
1

TIL

목록 보기
43/85
post-thumbnail

Redux Toolkit 이란? (RTK)

리덕스 툴킷은 우리가 이전에 배운 리덕스를 더 편하게 쓰기 위해 만든 것이다.
초기 세팅을 위해 쳐야 할 코드의 양이 많았던 개발자들의 불만을 수용해서 리덕스팀이 만들게 되었다.

리덕스 툴킷은 우리가 배운 리덕스의 구조나 패러다임이 모두 똑같다!
일일이 만들어주어야 했던 DUCKS 패턴의 요소들이 자동화 되었을 뿐이다.

우선 아래 패키지를 설치하자

yarn add react-redux @reduxjs/toolkit

count 프로그램의 코드를 비교하며 일반 리덕스와 리덕스툴킷의 차이점을 알아보자.

action value, action creator, reducer

일반 리덕스 (DUCKS 패턴)

// 일반 리덕스 예시 코드

// Action Value
const ADD_NUMBER = "ADD_NUMBER";
const MINUS_NUMBER = "MINUS_NUMBER";

// Action Creator
export const addNumber = (payload) => {
  return {
    type: ADD_NUMBER,
    payload,
  };
};

export const minusNumber = (payload) => {
  return {
    type: MINUS_NUMBER,
    payload,
  };
};

// Initial State
const initialState = {
  number: 0,
};

// Reducer
const counter = (state = initialState, action) => {
  switch (action.type) {
    case ADD_NUMBER:
      return {
        number: state.number + action.payload,
      };
    case MINUS_NUMBER:
      return {
        number: state.number - action.payload,
      };
    default:
      return state;
  }
};

// export default reducer
export default counter;

RTK

// src/redux/modules/counterSlice.js

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

const initialState = {
  number: 0,
};

const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    // 리듀서 안에서 만든 함수 자체가 리듀서의 로직이자, 액션크리에이터가 된다.
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
    },

    minusNumber: (state, action) => {
      state.number = state.number - action.payload;
    },
  },
});

// 액션크리에이터는 컴포넌트에서 사용하기 위해 export 하고
export const { addNumber, minusNumber } = counterSlice.actions;
// reducer 는 configStore에 등록하기 위해 export default 합니다.
export default counterSlice.reducer;

코드의 양이 눈에 띄게 줄었다!
큰 차이점은 Action Value 와 Action Creator를 이제 직접 생성해 주지 않고,
Action value, Action Creator, Reducer 가 하나로 합쳐졌다는 점이다.
createSlice만 사용하면 저 세 개를 각각 만들어 줄 필요 없이 한 번에 3개를 모두 만들 수 있다.

슬라이스 만 자세히 살펴보자.
createSlice 는 설정 정보 객체를 인자로 받는다.
그 안에 우리가 필수로 작성해 주어야 하는 값은 name, initialState, reducers 가 있다.

//createSlice API 뼈대

const counterSlice = createSlice({
	name: '', // 이 모듈의 이름
	initialState : {}, // 이 모듈의 초기상태 값
	reducers : {}, // 이 모듈의 Reducer 로직
})

configStore.js

일반 리덕스

// 일반 리덕스 combineReducers 예시 코드

import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter";

const rootReducer = combineReducers({
  counter,
});
const store = createStore(rootReducer);
export default store;

RTK

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

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

export default store;

createStore 대신에 configureStore를 사용한다.

RTK 의 좋은 점

Redux DevTools

리덕스 툴킷을 사용하면 좋은 점은 Redux DevTools 를 추가 설정 코드 없이 바로 사용할 수 있다는 것이다!

// 일반 리덕스
import { createStore, combineReducers } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import comment from "../modules/comment";

const rootReducer = combineReducers({
  comment,
});
const store = createStore(rootReducer, composeWithDevTools());

export default store;

기존에 일반 리덕스를 사용할 때는 composeWithDevTools 라는 API 를 사용했어야 했는데, RTK를 사용하면 devtools가 내장되어 있기 때문에 별도의 코드 설정 없이 크롬 확장프로그램만 설치하면 바로 사용이 가능하다~!!

mutable 해도 괜찮다

리액트에서 리렌더링을 일으키기 위해서는 불변성을 유지시키는 것이 중요하다.
그래서 state를 변경할 때마다 불변성을 고려하는 것이 중요했다.
그러나 RTK를 사용하면, 그 안에 immer 라는 라이브러리가 내장되어 있기 때문에 불변성을 유지하지 않아도 괜찮다...!

addTodo: (state, action) => {
      return [...state, action.payload];
    },

기존에 위와 같이 작성하던 것을

addTodo: (state, action) => {
      state.push(action.payload);
    },

mutable 한 배열 메서드인 push() 를 써도 전혀 문제가 되지 않는 것이다. 우리가 불변성을 지키지 않아도 immer 가 알아서 불변성을 대신 지켜준다.

redux에 이제 막 적응했는데 또 RTK에 적응하려니 쉽진 않겠지만,,
configStore.js, 리듀서 작성하는 부분만 약간 다르고 useSelector, useDispatch 사용하는 부분은 동일해서 금방 적응 할 수 있을 것 같다.
심화 주차가 새로 시작됐는데 이번 주도 힘내보자!

profile
느리더라도 조금씩, 꾸준히

0개의 댓글