TIL 41 | Redux Toolkit

song hyun·2022년 1월 2일
0

Redux

목록 보기
2/3
post-thumbnail

Redux Toolkit

리덕스를 사용하면서 언급되는 3가지 문제점은 아래와 같다.

  • 리덕스 스토어 환경 설정은 너무 복잡하다.
  • 리덕스를 유용하게 사용하려면 너무 많은 패키지를 추가해야한다.
  • 리덕스 보일러플레이트, 즉 어떤 일을 하기 위해서 꼭 작성해야 하는 코드를 너무 많이 요구한다.

이러한 문제점들을 해결하고자 RTK이 만들어졌다고 한다.

✌createStore ⇉ configureStore

// 🛠 createStore
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from './reducers';

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  rootReducer,
  composeEnhancers(applyMiddleware(thunk))
);
  • 기존 리덕스에서는 스토어(Store)를 생성하기 위해서는 createStore를 생성해야 했다.
  • combineReducres를 사용해 리듀서(Reducer)를 하나로 합쳐서 rootReducer를 인자로 받는다.
  • DevTools 사용시에는 두 번째 인자로 넣어주면 된다.
// ✨ configureStore
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
  reducer: {
    todos: todosReducer,
  },
});
  • RET에서는 별도의 combineReducres를 사용하지 않고, reducer 필드를 필수적으로 넣느다.
  • 그 안에 리듀서 함수를 넣으면 된다. 기본적으로 Redux DevTool을 제공한다.

✌action creator + action ⇉ createAction

// 🛠 action + action creator 
import axios from 'axios';

const ADD_TODO = 'ADD_TODO';

export const addTodo = (value) => async (dispatch) => {
  const response = await axios.post('http://localhost:5000/todos', {
    value: value,
  });
  dispatch({ type: ADD_TODO, payload: response });
};

기존 리덕스에서는 액션과 액션 생성자 함수를 별도로 만들어야 했다.

// ✨ createAction
import { createAction } from '@reduxjs/toolkit';

const addTodo = createAction('ADD_TODO');

const reducer = (state = [], action) => {
  switch (action.type) {
    case addTodo.type:
      return [
        {
          id: Date.now().toString(),
          value: action.payload,
        }, ...state];
    default:
      return state;
  }
}
  • RET에서는 createAction 호출하면 하나의 객체 action 객체를 생성한다.
  • action 객체는 type,payload 속성을 가지고 있다.
  • action 객체에 payload를 사용하여 다른 값을 전달할 수 있다.

✌Reducer ⇉ createReducer

// 🛠 reducer 
import { createAction } from '@reduxjs/toolkit';

const addTodo = createAction('ADD_TODO');

const reducer = (state = [], action) => {
  switch (action.type) {
    case addTodo.type:
      return [
        {
          id: Date.now().toString(),
          value: action.payload,
        }, ...state];
    default:
      return state;
  }
}
  • 기존 리덕스에서는 type을 찾을 때, switch문을 사용했었다.
  • 그러나 위에와 같은 방법은 보일러 코드도 많고, 가독성도 떨어진다는 단점이 있다.

// ✨ createReducer 
import { createAction, createReducer } from '@reduxjs/toolkit';
const addTodo = createAction('ADD_TODO');

const reducer = createReducer([], {
  [addToDo]: (state, action) => {
    state.push({ id: Date.now().toString(), value: action.payload });  
  }
})
  • RET에서는 createReducer를 사용하면, immutable 관리까지 자동으로 관리해주는 유틸 함수이다.
  • createReducerkey의 값은 createAction을 넣어서 사용한다.

✌action + reducer ⇉ createSlice

  • createSlice는 앞서 언급한createAction, createReducer 함수가 내부적으로 사용된다.
  • 선언된 슬라이스의 name 속성에 따라서 리듀서와 그것에 상응하는 액션 생성자와 액션 타입을 자동으로 생성한다.
// ✨ createSlice 
import { createSlice, nanoid } from "@reduxjs/toolkit";

const todos = createSlice({
  name: 'todos',
  initialState: []
  reducers: {
    addTodo: (state, acion) => {
      state.push({ id: nanoid(), value: acion.payload });
    },
})

✌immer

  • React를 통해 개발할 때는 불변성의 유지를 위해서, 직접 state를 건드리지 않고 복사하여 새로운 배열을 생성하는 arr.map, arr.filter, arr.concat등 과 같은 배열 함수를 사용해왔다.
  • RET의 createReducer, createSlice 함수는 불변성을 신경 쓰지 않아도 된다. 그 이유는 자동으로 불변성을 유지 Immer 라이브러리를 가지고 있기 때문이다.

Reference

Redux Toolkit →(SITE)
리덕스 툴킷은 정말 천덕꾸러기일까? →(BLOG)

profile
Front-end Developer 🌱

0개의 댓글