1차 공부/React공부

리덕스 툴킷

공대탈출 2022. 12. 10. 21:43

리덕스 툴킷은 전에 사용한 리덕스를 개량한 것이다.

ducks패턴의 요소들이 코드의 양을 늘리는 불만이 생겨, 코드는 적게, 사용은 편하게 하기위한 기능들을 흡수한 것이 리덕스 툴킷이다.

 

리덕스와 다른 새로운 것이아닌, 코드를 줄이기위한 API가 추가된 것이다.

컴포넌트에서 useSelector을 사용하는것도 똑같다.

모듈파일과 스토어파일의 차이점만 기억하면 된다.

 

툴킷 설치하기

yarn add react-redux @reduxjs/toolkit

 

 

기존의 리덕스

// 일반 리덕스 예시 코드

// 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;

action value, action creator, initial state, reducer... 별도로 작성할 게 많았다.

 

아래는 리덕스툴킷을 사용한 코드이다.

// 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가 하나로 합쳐졌다.

또한 우리는 Slice라는 API를 사용해서 각각 만들 필요없이 한번에 만들 수 있다.

 

 

슬라이스는 createSlice라는 API를 통해 만들 수 있다.

그리고 그 인자로 설정정보를 객체로 받는데, 그 안에 우리가 필수로 작성해줘야하는 값은 name, initialState, reducers가 있다.

//createSlice API 뼈대

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

 

위의 counterSlice 리듀서 객체 안에서 만들어주는 함수가 리듀서의 로직이 되면서도 동시에 Action Creator가 된다.

그리고 Action Value까지 함수의 이름을 따서 자동으로 만들어진다.

그래서 우리는 Reducer만 만들면 된다.

// counterSlice.js의 Slice 구조

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로 Action Creator을 내보내주었듯이 툴킷도 아래와같이 export해주면된다.

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

다음으로 configStore을 비교해보자.

 

먼저 우리가 했던 일반 리덕스의 store이다.

// 일반 리덕스 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;

 

다음으로 리덕스 툴킷에서의 store이다.

// src/redux/modules/config/configStore.js

import { configureStore } from "@reduxjs/toolkit";
/**
 * import 해온 것은 slice.reducer 입니다.
 */
import counter from "../modules/counterSlice";
import todos from "../modules/todosSlice";

/**
 * 모듈(Slice)이 여러개인 경우
 * 추가할때마다 reducer 안에 각 모듈의 slice.reducer를 추가해줘야 합니다.
 *
 * 아래 예시는 하나의 프로젝트 안에서 counter 기능과 todos 기능이 모두 있고,
 * 이것을 각각 모듈로 구현한 다음에 아래 코드로 2개의 모듈을 스토어에 연결해준 것 입니다.
 */
const store = configureStore({
  reducer: { counter: counter, todos: todos },
});

export default store;

 

그리도 생성한 store을 export default해서 최상위 index.js의 Provider에 주입한다.

// index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux";
import store from "./redux/config/configStore";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

그리고 원하는 페이지나 컴포넌트에서 useSelector을 사용해서 연결이 잘 되었는지 조회하여 확인해본다.

 

 

리덕스 devtools를 활용해서 state값이 어떻게 변하는지 확인한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'1차 공부 > React공부' 카테고리의 다른 글

immer란?  (0) 2022.12.10
Flux과 Redux (정리필요)  (0) 2022.12.10
HTTP, URI(URL, URN)  (0) 2022.12.03
payload  (0) 2022.12.02
Action Creator  (0) 2022.12.02