Redux Toolkit을 만나다.

김민찬·2022년 2월 26일
0

Redux

목록 보기
3/5
post-thumbnail
post-custom-banner

Redux Toolkit을 만나다

지금으로 부터 약 6개월 전 코드스테이츠에서 파이널 프로젝트를 진행하면서 퍼스트 프로젝트에서 느낀 props만으로 부모의 상태를 내려주니 더 나은 상태관리의 필요성을 느끼게 되었다.

Redux를 도입하려고 하니, 프론트 팀 3명이 Redux에 대한 이해가 필요한 기간에서 나오는 러닝 커브와 보일러 플레이트 코드가 너무 많다는 점에서 도입이 망설여졌다.
위의 두 문제를 해결하기에는 프로젝트 기간이 너무 짧았기 때문이다.

그래서 Redux를 사용하기 쉬운 방법이 없을까 하다가 발견한 것이 Redux Toolkit이었다.

입사후 회사에 도입

회사에 입사를 하고, 회사의 코드를 보는데 깜짝놀랐다.
Redux의 Store와 reducer들의 크기가 프로젝트 때와 달리 상상이상으로 방대했던 것이다.
immerredux-actions로 최대한 보일러 플레이트 코드를 줄일려고 노력했지만, 어쩔 수 없는 한계가 보였다.

그래서 나는 Toolkit의 도입을 추천했고 허가를 받아서 작업을 했다.
결과는 createSlice로 ducks 패턴을 그대로 유지하면서 코드의 길이는 2/3가량으로 줄어들었다.

코드의 예시는 다음과 같다.

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  value: 0 
};

const {actions, reducer} = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value++
    },
    decrement: (state) => {
      state.value--
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload
    },
  },
})

export const { increment, decrement, incrementByAmount } = actions;
export default reducer;

위의 예시처럼 state를 직접 변경할 수 있고, prefix를 자동으로 붙혀준다는 점, 그리고 action과 reducer를 생성하는 코드가 한눈에 들어오는 ducks패턴을 가지고 있다는 점이 가장 좋았다.

Prepare + nanoid

toolkit을 사용하면서 아쉬운 점들이 있었다.
redux를 사용하기 쉬워진 것 까지는 좋은데 거기서 더 이상 발전을 못한 것이다.
그래서 여러가지를 고민하다가 최근에는 prepare를 도입하려고 시도 중이다.

prepare는 리듀서가 실행되기 이전에 액션의 내용을 편집할 수 있다.

prepare라는 이름처럼 actions을 강탈하는 느낌이다.
reducer가 실행되기 이전에 action을 편집 하고 리턴해 주면 된다.
그래서 action에 payload를 추가할때 활용할 수 있다.

추가 적으로 prepare를 공부하면서 알게된 내용인데 toolkit에는 기본적으로 nanoid가 내장되어 있다.
nanoid는 랜덤하게 유니크한 값을 생성한다.

아래는 코드 예시다.

import { createSlice, nanoid } from '@reduxjs/toolkit';
import moment from 'moment';

const initialState = {
    total: [],
};

const { actions, reducer } = createSlice({
    name: 'todo',
    initialState,
    reducers: {
        setAddToTotal: {
            reducer: (state, action) => {
                state.total.unshift(action.payload);
            },
            prepare: ({ content }) => {
                const id = nanoid();
                const now = moment().unix();
                return { payload: { content, id, now } };
            },
        },
    },
});

export const { setAddToTotal } = actions;
export default reducer;

아직 extraReducers과 createAsyncThunk는 사용해보지 않았는데 추가적으로 공부해서 사용하고 싶다.

profile
두려움 없이
post-custom-banner

0개의 댓글