|
1 | 1 | ---
|
2 | 2 | title: History
|
3 |
| -description: A Jōtai utility package for advanced state history management |
4 |
| -nav: 5.02 |
5 |
| -keywords: history,undo,redo,jotai |
| 3 | +description: A Jōtai utility package for state history |
| 4 | +nav: 4.04 |
| 5 | +keywords: history, undo, redo, track changes |
6 | 6 | ---
|
7 | 7 |
|
8 |
| -[jotai-history](https://github.com/jotaijs/jotai-history) is a utility package for advanced state history management. |
| 8 | +[jotai-history](https://github.com/jotaijs/jotai-history) is a utility package for tracking state history in Jotai. |
9 | 9 |
|
10 |
| -## install |
| 10 | +## Installation |
11 | 11 |
|
12 | 12 | ```
|
13 | 13 | npm install jotai-history
|
14 | 14 | ```
|
15 | 15 |
|
16 |
| -## withHistory |
| 16 | +## `withHistory` |
17 | 17 |
|
18 |
| -### Signature |
19 |
| - |
20 |
| -```ts |
21 |
| -declare function withHistory<T>(targetAtom: Atom<T>, limit: number): Atom<T[]> |
22 |
| -``` |
| 18 | +```js |
| 19 | +import { withHistory } from 'jotai-history' |
23 | 20 |
|
24 |
| -This function creates an atom that keeps a history of states for a given `targetAtom`. The `limit` parameter determines the maximum number of history states to keep. |
25 |
| -This is useful for tracking the changes over time. |
| 21 | +const targetAtom = atom(0) |
| 22 | +const limit = 2 |
| 23 | +const historyAtom = withHistory(targetAtom, limit) |
26 | 24 |
|
27 |
| -The history atom tracks changes to the `targetAtom` and maintains a list of previous states up to the specified `limit`. When the `targetAtom` changes, its new state is added to the history. |
| 25 | +function Component() { |
| 26 | + const [current, previous] = useAtomValue(historyAtom) |
| 27 | + ... |
| 28 | +} |
| 29 | +``` |
28 | 30 |
|
29 |
| -### Usage |
| 31 | +### Description |
30 | 32 |
|
31 |
| -```jsx |
32 |
| -import { atom, useAtomValue, useSetAtom } from 'jotai' |
33 |
| -import { withHistory } from 'jotai-history' |
| 33 | +`withHistory` creates an atom that tracks the history of states for a given `targetAtom`. The most recent `limit` states are retained. |
34 | 34 |
|
35 |
| -const countAtom = atom(0) |
36 |
| -const countWithPrevious = withHistory(countAtom, 2) |
| 35 | +### Action Symbols |
37 | 36 |
|
38 |
| -function CountComponent() { |
39 |
| - const [count, previousCount] = useAtomValue(countWithPrevious) |
40 |
| - const setCount = useSetAtom(countAtom) |
| 37 | +- **RESET** |
| 38 | + Clears the entire history, removing all previous states (including the undo/redo stack). |
41 | 39 |
|
42 |
| - return ( |
43 |
| - <> |
44 |
| - <p>Count: {count}</p> |
45 |
| - <p>Previous Count: {previousCount}</p> |
46 |
| - <button onClick={() => setCount((c) => c + 1)}>Increment</button> |
47 |
| - </> |
48 |
| - ) |
49 |
| -} |
50 |
| -``` |
| 40 | + ```js |
| 41 | + import { RESET } from 'jotai-history' |
51 | 42 |
|
52 |
| -## withUndo |
| 43 | + ... |
53 | 44 |
|
54 |
| -### Signature |
| 45 | + function Component() { |
| 46 | + const setHistoryAtom = useSetAtom(historyAtom) |
| 47 | + ... |
| 48 | + setHistoryAtom(RESET) |
| 49 | + } |
| 50 | + ``` |
55 | 51 |
|
56 |
| -```ts |
57 |
| -type Undoable = { |
58 |
| - undo: () => void |
59 |
| - redo: () => void |
60 |
| - canUndo: boolean |
61 |
| - canRedo: boolean |
62 |
| -} |
63 |
| -declare function withUndo<T>( |
64 |
| - targetAtom: WritableAtom<T, [T], any>, |
65 |
| - limit: number, |
66 |
| -): Atom<Undoable> |
67 |
| -``` |
| 52 | +- **UNDO** and **REDO** |
| 53 | + Moves the `targetAtom` backward or forward in its history. |
68 | 54 |
|
69 |
| -`withHistory` provides undo and redo capabilities for an atom. It keeps track of the value history of `targetAtom` and provides methods to move back and forth through that history. |
| 55 | + ```js |
| 56 | + import { REDO, UNDO } from 'jotai-history' |
70 | 57 |
|
71 |
| -The returned object includes: |
| 58 | + ... |
72 | 59 |
|
73 |
| -- `undo`: A function to revert to the previous state. |
74 |
| -- `redo`: A function to advance to the next state. |
75 |
| -- `canUndo`: A boolean indicating if it's possible to undo. |
76 |
| -- `canRedo`: A boolean indicating if it's possible to redo. |
| 60 | + function Component() { |
| 61 | + const setHistoryAtom = useSetAtom(historyAtom) |
| 62 | + ... |
| 63 | + setHistoryAtom(UNDO) |
| 64 | + setHistoryAtom(REDO) |
| 65 | + } |
| 66 | + ``` |
77 | 67 |
|
78 |
| -### Usage |
| 68 | +### Indicators |
79 | 69 |
|
80 |
| -```jsx |
81 |
| -import { atom, useAtom, useAtomValue } from 'jotai' |
82 |
| -import { withUndo } from 'jotai-history' |
| 70 | +- **canUndo** and **canRedo** |
| 71 | + Booleans indicating whether undo or redo actions are currently possible. These can be used to disable buttons or conditionally trigger actions. |
83 | 72 |
|
84 |
| -const counterAtom = atom(0) |
85 |
| -const undoCounterAtom = withUndo(counterAtom, 5) |
| 73 | + ```jsx |
| 74 | + ... |
86 | 75 |
|
87 |
| -function CounterComponent() { |
88 |
| - const { undo, redo, canUndo, canRedo } = useAtomValue(undoCounterAtom) |
89 |
| - const [value, setValue] = useAtom(counterAtom) |
| 76 | + function Component() { |
| 77 | + const history = useAtomValue(historyAtom) |
90 | 78 |
|
91 |
| - return ( |
92 |
| - <> |
93 |
| - <p>Count: {value}</p> |
94 |
| - <button onClick={() => setValue((c) => c + 1)}>Increment</button> |
95 |
| - <button onClick={undo} disabled={!canUndo}> |
96 |
| - Undo |
97 |
| - </button> |
98 |
| - <button onClick={redo} disabled={!canRedo}> |
99 |
| - Redo |
100 |
| - </button> |
101 |
| - </> |
102 |
| - ) |
103 |
| -} |
104 |
| -``` |
| 79 | + return ( |
| 80 | + <> |
| 81 | + <button disabled={!history.canUndo}>Undo</button> |
| 82 | + <button disabled={!history.canRedo}>Redo</button> |
| 83 | + </> |
| 84 | + ) |
| 85 | + } |
| 86 | + ``` |
105 | 87 |
|
106 | 88 | <CodeSandbox id="g6qj3q" />
|
107 | 89 |
|
108 | 90 | ## Memory Management
|
109 | 91 |
|
110 |
| -⚠️ Since `withHistory` and `withUndo` keeps a history of states, it's important to manage memory by setting a reasonable `limit`. Excessive history can lead to memory bloat, especially in applications with frequent state updates. |
| 92 | +> Because `withHistory` maintains a list of previous states, be mindful of memory usage by setting a reasonable `limit`. Applications that update state frequently can grow significantly in memory usage. |
0 commit comments