어떻게 합치는지는 이해하기 쉽다. 그런데 정작 사용하려니 useSelector를 사용한 component부터 어떻게 작동하는지 그 원리를 이해하기가 굉장히 까다로웠다.
일단 전체적인 코드부터 보자.
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;
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,
});
import { Action } from 'redux';
export type State = Date;
export type SetClockAction = Action<'@clock/setClock'> & {
payload: State;
};
export type Actions = SetClockAction;
import type * as T from './types';
export const setClock = (payload: T.State): T.SetClockAction => ({
type: '@clock/setClock',
payload,
});
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()))
- ClockTest.tsx가 setClock 함수를 dispatch 한다.
type: '@clock/setClock', payload,
- setClock은 action creator function으로 새로운 날짜를 인자로 받는다. 이 함수는 action 객체를 반환하는데, type(= '@clock/setClock')과 payload를 가지고 있다.
- 이 action이 Redux store로 보내진다(dispatch).
- Redux store는 rootReducer에서 '@clock/setClock' 액션이 바꾸고자 하는 state를 찾는다.
switch (action.type) { case '@clock/setClock': return action.payload;
- reducers.ts에 '@clock/setClock' 타입에 대한 action이 있으므로 그에 맞게 state를 변경한다. (여기서는 action.payload, 즉 처음에 setClock 함수의 인자로 준 new Date()를 반환)
- useSelector에 의해 바뀐 state에 따라 ClockTest.tsx 컴포넌트가 재렌더링 된다.