Files
2nd/10_Wiki/Topics/Architecture/상태 머신 (State Machine) 모델링 및 Redux 액션_리듀서 설계.md
T
koriweb d8a80f6272 chore(wiki): dangling 링크 canonical 정규화 (768파일/1200건)
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해
끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은
과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업.
도구: Datacollect/scripts/link_reconcile_apply.mjs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:24:15 +09:00

207 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-상태-머신-state-machine-모델링-및-redux-
title: 상태 머신 (State Machine) 모델링 및 Redux 액션/리듀서 설계
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [State Machine + Redux, FSM Redux Design, XState + Redux]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [state-machine, redux, xstate, frontend, architecture]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: redux-toolkit
---
# 상태 머신 (State Machine) 모델링 및 Redux 액션/리듀서 설계
## 매 한 줄
> **"매 impossible state 의 unrepresentable 화"**. 매 finite state machine (FSM) 는 explicit state + event + transition 의 enumerate. Redux reducer 는 매 (state, action) → state 의 pure function — 매 FSM 와 isomorphic. 2026 년 매 XState 5 + RTK 의 combine 패턴 의 standard.
## 매 핵심
### 매 FSM 5-tuple
- **States (Q)**: enumerable set — `idle | loading | success | error`.
- **Events (Σ)**: external triggers — `FETCH | RESOLVE | REJECT`.
- **Transitions (δ)**: `Q × Σ → Q` — 매 partial function.
- **Initial state (q₀)**: `idle`.
- **Final states (F)**: optional — terminal nodes.
### 매 Redux 와 mapping
- **Reducer = δ**: `(state, action) => newState` 의 pure transition.
- **Action = Σ event**: typed discriminated union.
- **Store state = Q**: 매 status field 의 enum.
- **Selector**: 매 derived view — `isLoading = state.status === 'loading'`.
### 매 응용
1. Form wizard — multi-step flow 의 state 의 explicit.
2. Data fetching — idle/loading/success/error 의 4-state.
3. Auth flow — anonymous/authenticating/authenticated/expired.
## 💻 패턴
### Discriminated union state
```typescript
type FetchState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; error: Error };
// 매 impossible state ('loading' + data) 의 unrepresentable.
```
### RTK slice = FSM reducer
```typescript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { status: 'idle' } as FetchState<User>,
reducers: {
fetch: (state) => {
if (state.status === 'idle' || state.status === 'error') {
return { status: 'loading' };
}
return state; // ignore invalid transition
},
resolve: (_, action: PayloadAction<User>) => ({
status: 'success',
data: action.payload,
}),
reject: (_, action: PayloadAction<Error>) => ({
status: 'error',
error: action.payload,
}),
},
});
```
### Transition guard table
```typescript
const TRANSITIONS = {
idle: { FETCH: 'loading' },
loading: { RESOLVE: 'success', REJECT: 'error' },
success: { FETCH: 'loading' },
error: { FETCH: 'loading' },
} as const;
function transition<S extends keyof typeof TRANSITIONS>(
state: S,
event: string
): string {
return (TRANSITIONS[state] as any)[event] ?? state;
}
```
### XState 5 + Redux integration
```typescript
import { createMachine, createActor } from 'xstate';
const fetchMachine = createMachine({
id: 'fetch',
initial: 'idle',
states: {
idle: { on: { FETCH: 'loading' } },
loading: {
invoke: {
src: 'fetchUser',
onDone: { target: 'success', actions: 'storeData' },
onError: 'error',
},
},
success: { on: { REFRESH: 'loading' } },
error: { on: { RETRY: 'loading' } },
},
});
const actor = createActor(fetchMachine).start();
actor.subscribe((snapshot) => store.dispatch({ type: 'fsm/sync', payload: snapshot.value }));
```
### Hierarchical (nested) state
```typescript
// 매 auth flow — 매 sub-state machine.
const authMachine = createMachine({
initial: 'unauthenticated',
states: {
unauthenticated: {
initial: 'idle',
states: {
idle: { on: { LOGIN: 'submitting' } },
submitting: { on: { SUCCESS: '#auth.authenticated', FAIL: 'idle' } },
},
},
authenticated: {
on: { LOGOUT: 'unauthenticated' },
},
},
}, { id: 'auth' });
```
### Parallel state regions
```typescript
const editorMachine = createMachine({
type: 'parallel',
states: {
document: { initial: 'clean', states: { clean: {}, dirty: {} } },
network: { initial: 'online', states: { online: {}, offline: {} } },
},
});
// 매 state = (document, network) 의 cross product — explicit.
```
### Test as transition table
```typescript
test.each([
['idle', 'FETCH', 'loading'],
['loading', 'RESOLVE', 'success'],
['loading', 'REJECT', 'error'],
['success', 'FETCH', 'loading'],
])('transition %s --%s--> %s', (from, event, to) => {
expect(transition(from, event)).toBe(to);
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Simple async (fetch) | RTK `createAsyncThunk` + discriminated union |
| Multi-step wizard | XState machine |
| Complex auth | XState hierarchical machine |
| Parallel concerns | XState parallel states |
| Pure UI toggle | useState (not Redux) |
**기본값**: RTK + discriminated union state. 복잡 시 XState 5.
## 🔗 Graph
- 부모: [[프론트엔드 및 UIUX 표준|Redux]]
- 변형: [[XState]]
- 응용: [[Data Fetching]]
- Adjacent: [[Discriminated Union]] · [[Pure Function]] · [[Event Sourcing]]
## 🤖 LLM 활용
**언제**: state 가 3+ 개 + transition 의 explicit rule 의 필요 시.
**언제 X**: simple boolean toggle 또는 single-shot async — 매 overkill.
## ❌ 안티패턴
- **Boolean explosion**: `isLoading + isError + isSuccess` — impossible state (true+true) 의 representable.
- **Implicit transition**: reducer 안 valid state check 의 X — 매 invalid transition 의 silently 발생.
- **God reducer**: 매 모든 logic 의 한 reducer — 매 split.
- **Side effect in reducer**: `fetch()` 의 reducer 내부 — 매 thunk/saga/middleware 사용.
## 🧪 검증 / 중복
- Verified (Hopcroft & Ullman *Automata Theory*; Redux docs; XState v5 docs 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — FSM↔Redux mapping + XState 5 patterns |