✍️ What I Learned/TIL

[TIL] Redux toolkit - createAction, createReducer, configureStore, createSlice

Jiwon() 2023. 8. 1. 21:10


1. createAction + reducer

  • rtk의 createAction 함수를 사용하여 action creator 정의
  • createAction 함수는 자동으로 action creator 함수를 생성하여 action object를 생성한다.
    • (ex. { type: 'ADD', payload: actionPayload })
  • 그 후 reducer 함수를 직접 정의하여, action type과 payload를 기반으로 상태가 어떻게 업데이트되는지를 지정
  • state가 변화하면 state를 직접 변경하지 않고, reducer 함수에서 새로운 state를 생성하여 반환

 

 


2. createAction + createReducer

  • rtk의 createAction 및 createReducer 함수를 모두 사용한다.
  • createAction 함수는 1번 방법과 마찬가지로 action creator를 정의하는데 사용
  • createReducer 함수는 reducer를 보다 간결하게 정의하고, action type에 따라 state 업데이트를 자동으로 처리하는 reducer 함수를 생성한다.
  • state를 직접 수정해도 immer의 존재 때문에 상태의 불변성이 유지되며, 새로운 state로 반환할 필요가 없음

 

RTK 2.0.0부터 createReducer 대신 builder callback 기반으로 변경

createReducer를 사용하면 콘솔에 아래와 같은 경고메시지가 발생한다.
bundle.js:1712 The object notation for createReducer is deprecated, and will be removed in RTK 2.0. Please use the 'builder callback' notation instead: https://redux-toolkit.js.org/api/createReducer
import shortid from "shortid";
import { createStore } from "redux";
import { createReducer, createAction, PayloadAction } from "@reduxjs/toolkit";

export type RootState = {
  todos: Todo[];
};

export type Todo = {
  id: string;
  text: string;
}

const ADD = "ADD";
const DELETE = "DELETE";

type AddAction = PayloadAction<string, typeof ADD>;
type DeleteAction = PayloadAction<string, typeof DELETE>;
type ActionType = AddAction | DeleteAction;

// createAction
export const addTodo = createAction<string>(ADD);
export const deleteTodo = createAction<string>(DELETE);

const initialState: RootState = {
  todos: [
    {
      id: shortid(),
      text: "리액트 공부하기"
    },
    {
      id: shortid(),
      text: "밥먹기",
    }
  ]
}

// redux-toolkit: createAction, createReducer with builder callback
const reducer = createReducer(initialState, (builder) => {
  builder
    .addCase(addTodo, (state, action: ActionType) => {
      state.todos.push({ text: action.payload, id: shortid() });
    })
    .addCase(deleteTodo, (state, action: ActionType) => {
      state.todos = state.todos.filter(todo => todo.id !== action.payload);
    });
});

const store = createStore(reducer);

export default store;

 

 


3. configureStore

  • 기존 createStore 함수보다 store 생성을 더 간편하게 할 수 있도록 하는 함수
  • middleware와 createStore 함수의 기능을 함께 갖고 있음
  • 기본적으로 Redux devtools 확장 및 Thunk 미들웨어를 포함

 

 


4. createSlice

  • createAction 함수와 createReducer 함수를 각각 사용하여 action과 reducer를 각각 생성할 필요 없이, 한번에 action과 reducer를 생성해주는 함수
import shortid from "shortid";
import { createStore } from "redux";
import { createSlice, configureStore, createReducer, createAction, PayloadAction } from "@reduxjs/toolkit";

export type RootState = {
  todos: Todo[];
};

export type Todo = {
  id: string;
  text: string;
}

const initialState: RootState = {
  todos: [
    {
      id: shortid(),
      text: "리액트 공부하기"
    },
    {
      id: shortid(),
      text: "밥먹기",
    }
  ]
}

// 3. createSlice
const todoSlice = createSlice({
  name: "todosReducer",
  initialState,
  reducers: {
    add: (state, action) => {
      state.todos.push({ text: action.payload, id: shortid() });
    },
    remove: (state, action) => {
      state.todos = state.todos.filter(todo => todo.id !== action.payload);
    }
  }
})

const store = configureStore({
  reducer: todoSlice.reducer
});

export const { add, remove } = todoSlice.actions;
export default store;