On a couch

[Redux-toolkit] slice 동적으로 추가하기 본문

프론트엔드 공부/React

[Redux-toolkit] slice 동적으로 추가하기

couch 2023. 2. 20. 18:15

레퍼런스

[Redux] 리덕스의 내부 파헤치기

replaceReducer on @reduxjs/toolkit

 

설명 / 정의

 

react 페이지의 크기가 커지면서, 모든 페이지를 한 번들로 가져오기 부담스러워 코드 분할을 하였다.

그러다보니 마찬가지로 redux store도 처음부터 모든 state를 들고 있을 것이 아니라, 해당 state가 필요한 곳에서만 동적으로 추가하도록 변경할 필요가 생겼다.

 

그래서 선배와 이것저것 뒤지다가 발견한 코드가 이것이다.

 

const staticReducers = {
  counter: counterReducerSlice,
};

export const store = configureStore({
  reducer: staticReducers,
  middleware: getDefaultMiddleware => [logger, ...getDefaultMiddleware()],
  enhancers: compose([monitorReducerEnhancer]),
});

1. 우선, 위와 같이 디폴트로 존재할 reducer들을 모아서 store를 생성해 둔다.

2. 예시에 있는 Middleware와 enhancer는 이 사례에 영향을 미치지 않는다.

store.asyncReducers = {};

store.injectReducer = (key, asyncReducer) => {
  store.asyncReducers[key] = asyncReducer;
  store.replaceReducer(mergeReducer(store.asyncReducers));
};

function mergeReducer(asyncReducers) {
  return combineReducers({
    ...staticReducers,
    ...asyncReducers
  });
}

3. asyncReducer를 만들어, 동적으로 추가할 reducer를 저장해두는 저장소로 쓴다.

4. injectReducer에 추가할 reducer와 그에 대한 key를 인자로 전달한다.

  • asyncReducer 안에 전달받은 key로 reducer를 넣는다
  • mergeReducer에 asyncReducers 객체를 인자로 넘겨서, 기존의 staticreducers와 asyncReducers 안의 reducer들을 하나의 reducer로 합친다.
  • replaceReducer를 써서, 기존의 reducer를 하나로 합쳐진 새 reducer로 바꾼다

5. 기존 reducer 및 state가 안전하게(immutable하게) 변경된다.

 

질문

이 코드가 바로 이해가 되지 않았던 이유는 2가지 의문이 들어서였다.

  1. 왜 store에 asyncReducers와 injectReducer라는 property를 직접 주입해도 되는 걸까? store 내부는 immutable하게 관리되어야 한다고 생각하고 있었는데..?
    ⇒ store 자체는 immutable할 필요가 없어서 괜찮다고 한다. redux가 신경쓰는 것은 그 한 단계 아래에 있는 state이다.

2. 이거 지금 reducer를 추가로 넣는 건데 이렇게 직접 추가해도 문제가 없나?? reducer를 추가하면 그게 관리하는 state도 따라서 추가되어야 하는 건데 이렇게 mutable하게 간다고? @.@
⇒ 질문이 틀렸다! reducer를 mutable하게 추가하고 있지 않다.

redux가 제공하는 combineReducers와 replaceReducer 메서드를 사용해 안전하게 병합하고 immutable하게 교체했다.

 

더 알아볼 것

store 해부하기

  • store를 console.log로 찍어 보면 안에 들어가 있는 property들의 정체
    • createStore는 store 안에 dispatch, subscribe, getState를 만들어 넣는다. 이것들을 통해 state에 접근할 때 예측 가능한 형태로 접근할 수 있다. store에 action을 dispatch하면 store는 reducer 함수를 호출하고, reducer는 actions 내용이 반영된 업데이트 된 새로운 state를 만든다.
  • store 안에 넣는 options의 정체
    • enhancer
    • middleware와 enhancer의 차이