반응형
(Ch05_2 의 내용을 기반으로 하고 있습니다.)
https://github.com/2jisu/do-it-react-with-ts/tree/main/Chapter05/02
https://github.com/yisj777s/doit-react-webapp-typescript/tree/main/ch05/ch05_2
Redux의 리듀서를 활용해서 몇 가지 만들어 보는 걸로 하기.
src/store 안에 파일들 사전 세팅
(store 안의 파일들 종류와 기능 다시 한 번 살펴 보기)
store/
├── // actions.ts → "뭘 할건지" 정의 (동작 함수 정의) <<< 이 글에서는 컴포넌트 별로 폴더를 나눠 각각 구현
├── AppState.ts → "전체 상태 구조" 정의 (어떤 데이터들이 있는지, 타입 정의)
├── index.ts → "스토어 설정" (모든 걸 합쳐서 스토어 만들기)
├── rootReducer.ts → "상태 변경 로직" 모음 (실제로 상태를 어떻게 바꿀지, switch/case 지정)
└── useStore.ts → "편리한 사용법" (컴포넌트에서 쉽게 쓸 수 있게, 커스텀 훅 느낌)
더보기
useStore.ts
import { configureStore } from "@reduxjs/toolkit";
import { useMemo } from "react";
import { rootReducer } from "./rootReducer";
const initializeStore = () => {
const store = configureStore({
reducer: rootReducer,
middleware: getDefaultMiddleware => getDefaultMiddleware()
})
return store
}
export function useStore() {
const store = useMemo(() => initializeStore(), [])
return store
}
AppState.ts
import * as Clock from './clock'
import * as Counter from './counter'
import * as R from './remoteUser'
import * as Cards from './cards'
export type AppState = {
clock: Clock.State
counter: Counter.State
remoteUser: R.State
cards: Cards.State
}
rootReducer.ts
import { combineReducers } from "redux";
import * as Clock from './clock'
import * as Counter from './counter'
import * as R from './remoteUser'
import * as Cards from './cards'
export const rootReducer = combineReducers({
clock: Clock.reducer,
counter: Counter.reducer,
remoteUser: R.reducer,
cards: Cards.reducer
})
index.ts
export * from './AppState'
export * from './useStore'
1. Clock
※ src/store 안에 clock 디렉토리를 만듭니다.
src/store/clock
더보기
types.ts
import type { Action } from "redux";
export type State = string
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().toISOString()
export const reducer = (state: T.State = initialState, action: T.Actions) => {
switch (action.type) {
case '@clock/setClock':
return action.payload
}
return state;
}
index.ts
export * from './types'
export * from './actions'
export * from './reducers'
src/App.tsx
import { Provider as ReduxProvider } from 'react-redux'
import { useStore } from './store'
import ClockTest from './pages/ClockTest'
export default function App() {
const store = useStore()
return (
<ReduxProvider store={store}>
<ClockTest />
</ReduxProvider>
)
}

2. Counter
※ src/store 안에 counter 디렉토리를 만듭니다.
src/store/counter
더보기
types.ts
import type { Action } from "redux";
export type State = number
export type SetCounterAction = Action<'@counter/setCounter'> & {
payload: State
}
export type Actions = SetCounterAction
actions.ts
import type * as T from './types'
export const setCounter = (payload: T.State): T.SetCounterAction => ({
type: '@counter/setCounter',
payload
})
export const increaseCounter = () => setCounter(1)
export const decreaseCounter = () => setCounter(-1)
reducers.ts
import * as T from './types'
const initialState: T.State = 0
export const reducer = (state: T.State = initialState, action: T.Actions) => {
switch (action.type) {
case '@counter/setCounter':
return state + action.payload
}
return state;
}
index.ts
export * from './types'
export * from './actions'
export * from './reducers'
src/App.tsx
import { Provider as ReduxProvider } from 'react-redux'
import { useStore } from './store'
import ClockTest from './pages/ClockTest'
import CounterTest from './pages/CounterTest'
export default function App() {
const store = useStore()
return (
<ReduxProvider store={store}>
<CounterTest />
<ClockTest />
</ReduxProvider>
)
}

반응형
'Front-End > React' 카테고리의 다른 글
| React #26 (Zustand) (1) | 2025.07.23 |
|---|---|
| React #25 (Redux toolkit - Slice + 실습 예제) (0) | 2025.07.23 |
| React #23 (훅, 상태관리 - 내장 useReducer vs Redux 패키지) (1) | 2025.07.22 |
| React #22 (api 통신 - fetch, promise) (0) | 2025.07.22 |
| React #21 (고급 훅 - useId, useTransition, useImperativeHandle) (1) | 2025.07.21 |