redux toolkit 정의 및 활용

soo's·2023년 4월 27일
0

TIL

목록 보기
43/53
post-thumbnail

0.redux toolkit

기존에 redux의 ducks pattern을 사용해서 상태를 관리했었는데, 타이핑할 코드가 굉장히 길어서 불편했었다. 그런 불편을 해소하기 위해 나온 것이 바로 redux toolkit이다.


// 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;
  1. 내가 만든 counterSlice는 액션객체와 리듀서 함수 모두를 가지고 있는 객체다. 얘는 모듈이라고 불러도 되고 redux toolkit 문서에서는 slice라는 이름으로 부르기도 한다.

  2. counterSlice는 createSlice라는 api를 사용해서 만들어낸 객체인데, 거기에는 꼭 반드시 reducers라는 키 값으로 내가 만들고 싶은 액션객체와 리듀서 함수를 담아야한다. 이거는 그냥 문법적 약속인거임

createSlice() 함수에서는 reducers라는 key를 사용하여 리듀서 함수를 정의합니다. 이것은 Redux Toolkit이 제공하는 문법 구조입니다. 따라서 reducers라는 key가 없는 경우, createSlice() 함수에서는 TypeError를 발생시킵니다.

reducers: {
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
    },

내가 이렇게 reducers라는 키 값에 만든 객체에는 action creator와 reducer 함수가 포함된거다. why? 걍 redux toolkit의 createSlice api가 그걸 해주는거임.
내가 {action creator name : reducer 함수 } 이렇게 작성하면
알아서 action creator에 대한 type도 만들고, 그 type일 때 실행할 reducer 함수도 만드는거임.

그리고 사용할 때는 반드시 counterSlice.actions coutnerSlice.reducer로 export 하면되는데, actions랑 reducer라는 이름도 toolkit 문법적 약속임. 다른 이름으로 접근하면 안됨

createSlice() 함수는 자동으로 각각의 액션 생성 함수에 대한 type 속성을 생성하므로, counterSlice.actions를 호출하면 이 객체에 접근할 수 있습니다. 예를 들어, addNumber() 액션 생성 함수의 type은 "counter/addNumber"입니다.

1. redux toolkit 설치

yarn add @reduxjs/toolkit

위의 명령어를 사용해서 redux toolkit을 설치해준다.

2. configStore 손 보기

// 일반 리덕스 combineReducers 코드

const rootReducer = combineReducers({
  counter,
});
const store = createStore(rootReducer);
export default store;

기존의 redux로 관리했던 configStore.js는 위와 같다.
combineReducers와 createStore를 사용해서 store를 정의했지만
redux toolkit을 사용하면 아래와 같이 간결하다.

// redux toolkit 사용 코드
import counter from "../modules/counterSlice";
import todos from "../modules/todosSlice";

const store = configureStore({
  reducer: { counter: counter, todos: todos },
});

export default store;

따라서 configureStore api로 여러 모듈(slice)를 하나의 reducer key에 담은 store 객체를 생성하고 이것을 export하면 된다.

3. 컴포넌트에서 사용하기

여러 slice를 하나의 store로 저장하는 작업을 2번에서 진행했다. 이때 기존의 모듈을 합쳐주는 작업을 configureStore api를 사용해서 진행했다.
그렇다면 나는 컴포넌트에서 내가 만든 모듈(slice)를 어떻게 사용해야 할까?

나는 처음에 아래와 같이 생각했다.

const counterState = useSelector((state)=> state.reducer.counter

하지만 아니다!
결론부터 말하자면

state.reducer.counter와 같이 reducer를 명시할 필요는 없습니다. 그 이유는 Redux Toolkit에서 configureStore() 함수를 사용하면, reducer 객체가 루트 리듀서 함수에 대한 여러 Slice 리듀서 함수를 하나로 합치는 작업을 수행하기 때문입니다. 따라서, configureStore() 함수를 사용하면 reducer 객체의 key 값으로 각각의 Slice 리듀서 함수를 등록하고, 이들을 하나의 루트 리듀서 함수로 합친 다음에, store에 등록합니다.

위와 같은 이유로 state.reducer.counter가 아닌 아래의 코드로 모듈을 사용할 수 있다.

const counterState = useSelector((state) => state.counter);

이후에 dispatch로 내가 export한 action creators를 사용하는 것은 redux 방식과 동일하다.


📌 참고

  1. Flux
    Flux는 Facebook에서 개발한 어플리케이션 아키텍처 패턴.
    Flux 아키텍처는 단방향 데이터 흐름을 기반으로 하며, 액션(action), 디스패처(dispatcher), 스토어(store)로 구성됨.
    redux toolkit은 facebook에서 만든 Flux 아키텍쳐를 기반으로, redux를 더 쉽고 간편하게 사용할 수 있게 해주는 것임 아래 링크는 flux에 대한 설명을 툰으로 보여주고 있음 참고!

Flux 아키텍쳐 참고

0개의 댓글