为 Jotai 提供全局撤销、重做功能的轻量扩展。
- 全局历史栈用于跟踪状态变更
- 差异化存储 实现最小内存占用
- O(1) atom 查找 使用 Map 获得快速性能
- 撤销和重做功能
- 分组操作以批量处理多个更改
- 自定义差异和补丁函数
- 历史限制
- 内存使用: 与完整状态存储相比减少 80-95%
- 性能: 典型应用速度提升 5-20 倍,大型应用可提升至 100 倍
- 效率: 使用 O(1) 查找代替 O(n) 查找原子
安装
npm i jotai-history-global
配置 Provider
// 导入
import {Provider} from "jotai";
import { historyStore } from 'jotai-history-global';
// 使用 Provider 包裹 App
// 并设置 store={historyStore}
<Provider store={historyStore}>
<App />
</Provider>
使用 atomWithHistory()
代替 Jotai 的 atom()
函数:
import { atomWithHistory } from 'jotai-history-global';
// 创建跟踪历史的原子
const counterAtom = atomWithHistory(0);
// 也可用创建更多,只要是 atomWithHistory,修改时都会被记录。
// const nameAtom = atomWithHistory('John');
// const todosAtom = atomWithHistory([{ id: 1, text: '学习 Jotai', done: false }]);
import { useAtom } from 'jotai';
import { useHistory } from 'jotai-history-global';
function MyComponent() {
const [counter, setCounter] = useAtom(counterAtom);
const { undo, redo, canUndo, canRedo } = useHistory();
return (
<div>
<p>计数器: {counter}</p>
<button onClick={() => setCounter(counter + 1)}>增加</button>
<button onClick={undo} disabled={!canUndo}>撤销</button>
<button onClick={redo} disabled={!canRedo}>重做</button>
</div>
);
}
您可以将多个操作分组到单个历史条目中:
const { groupOperations } = useHistory();
// 这将为所有操作创建一个单一的历史条目
groupOperations(() => {
setName('Jane');
setAge(30);
setLocation('纽约');
});
您可以控制何时记录历史:
// 仅在值变化超过10时跟踪变更
const scoreAtom = atomWithHistory(0, {
shouldTrack: (prev, next) => Math.abs(next - prev) > 10
});
用于内置差异逻辑不理想的复杂对象:
const complexDataAtom = atomWithHistory(initialData, {
// 自定义差异计算
customDiff: (prev, next) => {
// 仅返回变更部分
return { changedProperties: getOnlyChangedProps(prev, next) };
},
// 自定义补丁应用
customPatch: (value, diff) => {
// 将自定义差异应用到值
return { ...value, ...diff.changedProperties };
}
});
适用于差异可能比值本身更大的情况:
const smallObjectAtom = atomWithHistory(smallObject, {
useFullValueInstead: true // 存储完整值而不是差异
});
创建一个跟踪其历史记录以进行撤销/重做操作的原子。
选项包括:
id
:自定义标识符historyLimit
:最大历史条目数(默认:50)shouldTrack
:确定是否应跟踪变化的函数customDiff
:自定义差异函数customPatch
:自定义补丁函数useFullValueInstead
:强制使用完整值而不是差异
提供撤销/重做功能的钩子:
undo()
- 恢复到上一个状态redo()
- 应用下一个状态(撤销后)canUndo
- 是否有可撤销的状态canRedo
- 是否有可重做的状态clear()
- 清除历史栈groupOperations(callback)
- 将操作分组到单个历史条目中
createDiff(oldValue, newValue)
- 创建两个值之间的差异applyDiff(value, diff)
- 将差异应用到值reverseDiff(diff)
- 反转差异以进行撤销操作