useUndo
今天无意间看到一个有意思的库 useUndo,想着自己实现下。具体代码链接在文章末尾可见。
help function and state
// e.g
const [
countState,
{
set: setCount,
reset: resetCount,
undo: undoCount,
redo: redoCount,
canUndo,
canRedo
}
] = useUndo<number>(0);
const { present: presentCount } = countState;
useUndo 提供了几个功能set, undo, redo, reset
跟state
以及可执行操作状态的判断canUndo, canRedo
看到除了state
供消费之外,还提供了set
来做 dispatch 的操作;
紧接着是reset
用来重置所有的操作和 state;
undo,redo
两个其实就是 useUndo 的精髓所在了,可以理解为回显之前或之后的state snapshat
形容起来比较抽象;
最后的两个状态控制的变量canUndo, canRedo
来代表当前的undo, redo
是否可执行;
先看看官方在线例子 useUndo
state and set
其实上面我提到dispatch
已经有点那个意思了, 我第一感觉就是用useReducer
来管理state
core
其他的不想谈看看代码就懂了,主要想说说是如何做到 undo,redo
的。其实很简单,内部维护一个有序队列就行了,在每次做dispatch state
时候,需要去往这个队列尾加入最新·的state
。当undo
的时候需要去取最近的旧的 state, 这个时候内部的指针point
所在的位置就要往前移动一位,point
变化后所指的位置就是要显示的state
。同理redo
的操作反向而为就行了。当指针的位置不在尾部的时候,中途做了dispatch
的操作后,需要把当前队列中当前point
所在的位置之后的所有state snapshat
全移除掉 同时把新的state
再从尾部添加进去。其它的不谈了
实现代码地址 https://github.com/zy0228/useUndo/blob/main/src/useUndo.tsx