combineReducers 활용해서 reducer 합치기

LEEJAEJUN·2023년 5월 19일
0

react-typescript

목록 보기
3/7

combineReducers() 함수로 여러 reducer을 합치기

어떻게 합치는지는 이해하기 쉽다. 그런데 정작 사용하려니 useSelector를 사용한 component부터 어떻게 작동하는지 그 원리를 이해하기가 굉장히 까다로웠다.

일단 전체적인 코드부터 보자.

All Codes

- ClockTest.tsx

import { useDispatch, useSelector } from 'react-redux';
import { Title } from '../components';
import { useInterval } from '../hooks';
import { AppState } from '../store';
import * as C from '../store/clock';

const ClockTest = () => {
  const clock = useSelector<AppState, C.State>((state) => state.clock);
  const dispatch = useDispatch();
  useInterval(() => dispatch(C.setClock(new Date())));

  return (
    <section className="mt-4">
      <Title>ClockTest</Title>
      <div className="mt-4 flex flex-col items-center">
        <p className="text-bold text-2xl text-blue-600">{clock.toLocaleTimeString()}</p>
        <p className="text-bold text-lg text-blue-400">{clock.toLocaleDateString()}</p>
      </div>
    </section>
  );
};

export default ClockTest;

- rootReducers.ts

import { combineReducers } from 'redux';
import * as Cards from './cards';
import * as Clock from './clock';
import * as Counter from './counter';
import * as R from './remoteUser';

export const rootReducer = combineReducers({
  clock: Clock.reducer,
  counter: Counter.reducer,
  remoteUser: R.reducer,
  cards: Cards.reducer,
});

- types.ts

import { Action } from 'redux';

export type State = Date;

export type SetClockAction = Action<'@clock/setClock'> & {
  payload: State;
};

export type Actions = SetClockAction;

- actions.ts

import type * as T from './types';

export const setClock = (payload: T.State): T.SetClockAction => ({
  type: '@clock/setClock',
  payload,
});

- reducers.ts

import * as T from './types';

const initialState: T.State = new Date();

export const reducer = (state: T.State = initialState, action: T.Actions) => {
  switch (action.type) {
    case '@clock/setClock':
      return action.payload;
    default:
      return state;
  }
};

과정

dispatch(C.setClock(new Date()))
  1. ClockTest.tsx가 setClock 함수를 dispatch 한다.
type: '@clock/setClock',
payload,
  1. setClock은 action creator function으로 새로운 날짜를 인자로 받는다. 이 함수는 action 객체를 반환하는데, type(= '@clock/setClock')과 payload를 가지고 있다.
  2. 이 action이 Redux store로 보내진다(dispatch).
  3. Redux store는 rootReducer에서 '@clock/setClock' 액션이 바꾸고자 하는 state를 찾는다.
switch (action.type) {
    case '@clock/setClock':
      return action.payload;
  1. reducers.ts에 '@clock/setClock' 타입에 대한 action이 있으므로 그에 맞게 state를 변경한다. (여기서는 action.payload, 즉 처음에 setClock 함수의 인자로 준 new Date()를 반환)
  2. useSelector에 의해 바뀐 state에 따라 ClockTest.tsx 컴포넌트가 재렌더링 된다.
profile
always be fresh

0개의 댓글