Skip to content

Commit 3073d3a

Browse files
authored
feat(react): useHistoryState 개편 (#973)
* feat(react): useHistoryState 개편 * refac(react): useHistoryState import 영역 리팩토링 * fix(react): useIdle 이벤트 수정 * docs(react): useHistoryState js-doc 수정
1 parent 43478de commit 3073d3a

File tree

10 files changed

+502
-313
lines changed

10 files changed

+502
-313
lines changed

.changeset/solid-pianos-type.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@modern-kit/react': patch
3+
---
4+
5+
feat(react): useHistoryState 개편 - @ssi02014
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { useHistoryState } from '@modern-kit/react'
2+
import { useState } from 'react'
3+
4+
# useHistoryState
5+
6+
상태와 상태 변경 이력을 관리하는 훅입니다.
7+
8+
상태 변경 시마다 이력이 저장되며, 상태 히스토리를 이전(`back`)과 다음(`forward`)으로 이동할 수 있습니다. 또한 특정 시점의 상태로 이동(`go`)할 수 있으며, 현재 상태를 대체(`replaceState`)할 수 있습니다.
9+
10+
저장되는 이력의 최대 개수(`capacity`)를 제한할 수 있습니다.
11+
12+
## Code
13+
[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/react/src/hooks/useHistoryState/index.ts)
14+
15+
## Interface
16+
```ts title="typescript"
17+
interface UseHistoryStateReturn<T> {
18+
state: T; // 현재 상태 값
19+
canForward: boolean; // 다음 상태로 이동할 수 있는지 여부
20+
canBack: boolean; // 이전 상태로 이동할 수 있는지 여부
21+
setState: (newState: T | ((prevState: T) => T)) => void;
22+
// 상태 히스토리에 상태를 추가하고 새로운 상태로 업데이트합니다.
23+
replaceState: (newState: T | ((prevState: T) => T)) => void;
24+
// 상태 히스토리의 현재 상태를 대체합니다.
25+
back: () => void; // 상태 히스토리에서 이전 상태로 되돌리는 함수
26+
forward: () => void; // 상태 히스토리에서 다음 상태로 이동하는 함수
27+
go: (index: number) => void; // 상태 히스토리에서 특정 인덱스의 상태로 이동하는 함수
28+
}
29+
```
30+
```ts title="typescript"
31+
function useHistoryState<T>(
32+
initialValue: T | (() => T),
33+
capacity?: number): UseHistoryStateReturn<T>;
34+
```
35+
36+
## Usage
37+
```tsx title="typescript"
38+
import { useHistoryState } from '@modern-kit/react'
39+
40+
const Example = () => {
41+
const {
42+
state,
43+
canBack,
44+
canForward,
45+
setState,
46+
replaceState,
47+
back,
48+
forward,
49+
go
50+
} = useHistoryState(0, 5);
51+
52+
return (
53+
<div>
54+
<p>{state}</p>
55+
<button onClick={() => setState(state + 1)}>+1 (새 히스토리)</button>
56+
<button onClick={() => replaceState(state + 10)}>+10 (히스토리 교체)</button>
57+
<button onClick={back}>← 이전</button>
58+
<button onClick={forward}>다음 →</button>
59+
<button onClick={() => go(0)}>처음으로</button>
60+
<button onClick={() => go(-1)}>마지막으로</button>
61+
</div>
62+
)
63+
}
64+
```
65+
66+
## Example
67+
68+
export const Example = () => {
69+
const {
70+
state,
71+
canBack,
72+
canForward,
73+
setState,
74+
replaceState,
75+
back,
76+
forward,
77+
go
78+
} = useHistoryState(0, 5);
79+
80+
// 공통 버튼 스타일
81+
const buttonBaseStyle = {
82+
padding: '10px 12px',
83+
border: 'none',
84+
borderRadius: '4px',
85+
fontSize: '14px',
86+
cursor: 'pointer'
87+
};
88+
89+
const getButtonStyle = (bgColor, textColor = 'white', disabled = false) => ({
90+
...buttonBaseStyle,
91+
backgroundColor: disabled ? '#e9ecef' : bgColor,
92+
color: disabled ? '#6c757d' : textColor,
93+
cursor: disabled ? 'not-allowed' : 'pointer'
94+
});
95+
96+
const containerStyle = {
97+
padding: '20px',
98+
border: '1px solid #e2e2e2',
99+
borderRadius: '8px',
100+
backgroundColor: '#fafafa',
101+
maxWidth: '500px'
102+
};
103+
104+
const gridStyle = {
105+
display: 'grid',
106+
gap: '8px'
107+
};
108+
109+
return (
110+
<div style={containerStyle}>
111+
<div style={{ textAlign: 'center', marginBottom: '20px' }}>
112+
<h3 style={{ fontSize: '24px', color: '#333', margin: '0 0 8px 0' }}>
113+
현재 값: <span style={{ color: '#007acc' }}>{state}</span>
114+
</h3>
115+
<p style={{ fontSize: '14px', color: '#666', margin: '0' }}>
116+
뒤로가기 <strong>{canBack ? '가능' : '불가능'}</strong> |
117+
앞으로가기 <strong>{canForward ? '가능' : '불가능'}</strong>
118+
</p>
119+
</div>
120+
121+
<div style={{
122+
...gridStyle,
123+
gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
124+
marginBottom: '16px'
125+
}}>
126+
<button
127+
onClick={() => setState(state + 1)}
128+
style={getButtonStyle('#007acc')}
129+
>
130+
+1 (새 히스토리)
131+
</button>
132+
<button
133+
onClick={() => replaceState(state + 10)}
134+
style={getButtonStyle('#28a745')}
135+
>
136+
+10 (히스토리 교체)
137+
</button>
138+
</div>
139+
140+
<div style={{
141+
...gridStyle,
142+
gridTemplateColumns: 'repeat(auto-fit, minmax(100px, 1fr))'
143+
}}>
144+
<button
145+
onClick={back}
146+
disabled={!canBack}
147+
style={getButtonStyle('#6c757d', 'white', !canBack)}
148+
>
149+
← 이전
150+
</button>
151+
<button
152+
onClick={forward}
153+
disabled={!canForward}
154+
style={getButtonStyle('#6c757d', 'white', !canForward)}
155+
>
156+
다음 →
157+
</button>
158+
<button
159+
onClick={() => go(0)}
160+
style={getButtonStyle('#17a2b8')}
161+
>
162+
처음으로
163+
</button>
164+
<button
165+
onClick={() => go(-1)}
166+
style={getButtonStyle('#ffc107', '#212529')}
167+
>
168+
마지막으로
169+
</button>
170+
</div>
171+
</div>
172+
)
173+
};
174+
175+
<Example />

docs/docs/react/hooks/useStateWithHistory.mdx

Lines changed: 0 additions & 64 deletions
This file was deleted.

packages/react/src/hooks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export * from './useScrollEvent';
4747
export * from './useScrollLock';
4848
export * from './useScrollTo';
4949
export * from './useSessionStorage';
50-
export * from './useStateWithHistory';
50+
export * from './useHistoryState';
5151
export * from './useStep';
5252
export * from './useStepState';
5353
export * from './useThrottle';

0 commit comments

Comments
 (0)