Pandaman Blog

[React.js]Redux Toolkit를 이용해 TodoList만들기 본문

Front end/React

[React.js]Redux Toolkit를 이용해 TodoList만들기

oyg0420 2020. 4. 21. 21:58

Redux toolkit은 Redux를 좀 더 편리하게 사용할 수 있도록 만들어진 라이브러리입니다. 사용방법도 매우 간단합니다.
이전 포스팅에서 만들어본 todoList를 Redux toolkit에서 제공하는 함수를 사용해보겠습니다.

설치

# NPM
npm install @reduxjs/toolkit

# Yarn
yarn add @reduxjs/toolkit

configureStore

createStore 함수와 동일하게 루트 리듀서 함수를 호출하여 리덕스 스토어 생성하는 역할을 합니다. configureStore는 인자로 object를 받으며 아래와 같이 작성할 수 있습니다.

// 이전
const store = createStore(rootReducer, devTools);


// 이후
const store = configureStore({ reducer: rootReducer });

rootReducer는 인자로 reducer 속성으로 주입해야 합니다. middleware도 역시 아래와 같이 작성할 수 있습니다.

const store = configureStore({ reducer: rootReducer, middleware: [thunk, logger] });

createAction

createAction은 액션 타입과 payload를 리턴하는 함수 생성합니다.
이전에서 생성한 액션 함수와 한번 비교해보겠습니다.

export const ADDTODO = "todoList/ADDTODO";
export const DELETETODO = "todoList/DELETETODO";

// 이전
// export const addTodo = ({ id, title, description }) => ({
//   type: ADDTODO,
//   id,
//   title,
//   description,
// });

// export const deleteTodo = (id) => ({
//   type: DELETETODO,
//   id,
// });

// 이후
export const addTodo = createAction(ADDTODO); // return { type: 'todoList/ADDTODO' }
// addTodo({ id, title, description }) -> return { type: 'todoList/ADDTODO', payload: { id, title, description } }
export const deleteTodo = createAction(DELETETODO); // return { type: 'todoList/DELETETODO' }
// deleteTodo({id}) -> return { type: 'todoList/DELETETODO', payload: { id } }

매우 간단하게 변경되었습니다.

createReducer

일반적으로 reducer에서는 switch, if 조건문에 따라 acion.type을 확인하고 특정 로직을 수행합니다.
createReducer는 조건문이 필요 없이 사용할 수 있습니다.
이 부분은 todoList 프로젝트에는 적용을 하지 않았습니다..
Redux toolkit 공식 홈페이지에 있는 예제로 보여드리겠습니다.

// 이전
function counter(state = 0, action) {
  switch (action.type) {
    case increment.type:
      return state + 1
    case decrement.type:
      return state - 1
    default:
      return state
  }
}

// 이후
const counter = createReducer(0, {
  [increment.type]: state => state + 1,
  [decrement.type]: state => state - 1
})

createReducer을 사용한다면 지긋지긋한 조건문을 필요 없습니다.
이런 형태의 object을 공식문서에서는 lookup table object라고 부르네요.

createSlice

Ducks 패턴이라고 들어보셨나요? 저는 이 프로젝트의 리덕스 디렉터리 구조를 actions, reducers로 나눴습니다. 수정할 때 각각의 파일에 찾아가야 하는 번거로움이 있습니다. Ducks 패턴은 이러한 번거로움을 없애기 위해 액션 타입, 액션, 리듀서를 한 페이지에 작성된 패턴을 말합니다.
Redux-toolkit의 createSlice 함수는 ducks pattern을 사용하기 위한 용도입니다.

createSlice({
  name: 'reduxTest',
  initialState; [],
  reducers: { 
   first(state) { 
   // first 액션에 들어갈 로직
   }, 
   second(state) {
   // second 액션에 들어갈 로직
   }}          
})

name속성은 액션의 prefix에 해당하는 이름을 나타냅니다.
initialState는 초기 상태를 나타냅니다.
reducers의 key가 액션 타입의 문자열이고 key에 해당하는 로직은 우리가 reducers에 switch 또는 createReducer를 사용하며 작성된 로직이 들어갑니다. 'first' 액션이 발생한다면 액션 타입은 'reduxTest/first'가 됩니다.

한번 작성된 createSlice을 확인하겠습니다.

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

/**
 * using redux-toolkit: createSlice
 */
const todoListSlice = createSlice({
  name: "todoList",
  initialState: [],
  reducers: {
    addTodo(state, { payload }) {
      return [
        ...state,
        {
          id: payload.id,
          title: payload.title,
          description: payload.description,
        },
      ];
    },
    deleteTodo(state, { payload }) {
      const nextState = state.filter((todo) => todo.id !== payload.id);
      return nextState;
    },
  },
});

export const { addTodo, deleteTodo } = todoListSlice.actions;

export default todoListSlice.reducer;

액션의 prefix가 되는 문자열은 'todoList'입니다. 초기 상태 값은 empry array입니다. reducers에는 addTodo, deleteTodo가 발생할 때 적용될 로직입니다. 작성이 완료되었다면 마지막으로 다른 파일에서 actions와 reducer를 사용하기 위해 export 해야 합니다.

Redux-toolkit 어떠셨나요? redux를 간편하고 가독성 있게 만들어주는 좋은 녀석이라고 생각합니다.

여러분들도 이전 포스팅에 연습 삼아 적용해보길 추천합니다. 공식 홈페이지에서 더욱 자세한 내용을 확인할 수 있습니다.

Comments