Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): update docs for jotai-history #2736

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions docs/third-party/history.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: History
description: A Jōtai utility package for advanced state history management
nav: 5.02
keywords: history,undo,redo,jotai
---

[jotai-history](https://github.com/jotaijs/jotai-history) is a utility package for advanced state history management.

## install

```
npm i jotai-history
```

## withHistory

### Signature

```ts
declare function withHistory<T>(targetAtom: Atom<T>, limit: number): Atom<T[]>
```

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.
This is useful for tracking the changes over time.

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.

### Usage

```jsx
import { atom, useAtomValue, useSetAtom } from 'jotai'
import { withHistory } from 'jotai-history'

const countAtom = atom(0)
const countWithPrevious = withHistory(countAtom, 2)

function CountComponent() {
const [count, previousCount] = useAtomValue(countWithPrevious)
const setCount = useSetAtom(countAtom)

return (
<>
<p>Count: {count}</p>
<p>Previous Count: {previousCount}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
</>
)
}
```

## withUndo

### Signature

```ts
type Undoable = {
undo: () => void
redo: () => void
canUndo: boolean
canRedo: boolean
}
declare function withUndo<T>(
targetAtom: WritableAtom<T, [T], any>,
limit: number,
): Atom<Undoable>
```

`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.

The returned object includes:

- `undo`: A function to revert to the previous state.
- `redo`: A function to advance to the next state.
- `canUndo`: A boolean indicating if it's possible to undo.
- `canRedo`: A boolean indicating if it's possible to redo.

### Usage

```jsx
import { atom, useAtom, useAtomValue } from 'jotai'
import { withUndo } from 'jotai-history'

const counterAtom = atom(0)
const undoCounterAtom = withUndo(counterAtom, 5)

function CounterComponent() {
const { undo, redo, canUndo, canRedo } = useAtomValue(undoCounterAtom)
const [value, setValue] = useAtom(counterAtom)

return (
<>
<p>Count: {value}</p>
<button onClick={() => setValue((c) => c + 1)}>Increment</button>
<button onClick={undo} disabled={!canUndo}>
Undo
</button>
<button onClick={redo} disabled={!canRedo}>
Redo
</button>
</>
)
}
```

<CodeSandbox id="g6qj3q" />

## Memory Management

⚠️ 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.