实现撤销和重做功能一定需要 redux-undo 吗?不一定,redux 文档中提到,用 redux 轻而易举地实现撤销历史。
但是,有没有一个库能帮助我们实现可撤销功能,而不是由我们自己编写呢?当然有!来看看 Redux Undo,它可以为你的 Redux 状态树中的任何部分提供撤销和重做功能。
如何在现有的代码中接入 redux-undo
这是你的 Store
import { configureStore } from "@reduxjs/toolkit";
import todoListReducer, { TodoItemType } from "./todoList";
export default configureStore({
reducer: {
todoList: todoListReducer,
},
});
引入 redux-undo
import { configureStore } from "@reduxjs/toolkit";
import undoable, { excludeAction, StateWithHistory } from "redux-undo";
import todoListReducer, { TodoItemType } from "./todoList";
export type StateType = {
todoList: StateWithHistory<TodoItemType[]>;
};
export default configureStore({
reducer: {
todoList: undoable(todoListReducer),
},
});
限制撤销的步数
export default configureStore({
reducer: {
todoList: undoable(todoListReducer, {
limit: 20, // 限制只能撤销 20 步
}),
},
});
屏蔽某些 action ,不进行 undo redo
export default configureStore({
reducer: {
todoList: undoable(todoListReducer, {
//...
filter: excludeAction(["todoList/toggleCompleted"])
}),
},
});
redux-undo 作为 Redux 的一个中间件,几乎可以实现无痛接入。
撤销/重做
快照: 撤销历史可以定期或在每个操作之后保存应用程序状态的快照。这些快照捕获了应用程序状态的当前状态,以便稍后可以还原。
撤销操作: 当用户要撤销操作时,应用程序可以将状态还原到以前的快照或操作记录。这会导致应用程序回到先前的状态,好像之前的操作从未发生过。
重做操作: 如果用户决定撤销的操作实际上是一个错误,他们可能希望重新执行它。撤销历史应该允许用户执行重做操作,以将应用程序状态恢复到较新的状态。
模拟过程
{
todoList: {
past: [
{ id: '6', title: 'React' },
{ id: '7', title: 'Vue' },
{ id: '8', title: 'Redux' },
{ id: '9', title: 'Immer' }
],
present: [ { id: '10', title: 'Pina' } ],
future: []
}
}
现在撤销一步
{
todoList: {
past: [
{ id: '6', title: 'React' },
{ id: '7', title: 'Vue' },
{ id: '8', title: 'Redux' }
],
present: [ { id: '9', title: 'Immer' } ],
future: [ { id: '10', title: 'Pina' } ]
}
}
再按一次:
{
todoList: {
past: [
{ id: '6', title: 'React' },
{ id: '7', title: 'Vue' }
],
present: [ { id: '8', title: 'Redux' } ],
future: [
{ id: '9', title: 'Immer' },
{ id: '10', title: 'Pina' }
]
}
}
按下“重做”,我们希望往未来的状态移动一步:
{
todoList: {
past: [
{ id: '6', title: 'React' },
{ id: '7', title: 'Vue' },
{ id: '8', title: 'Redux' }
],
present: [ { id: '9', title: 'Immer' } ],
future: [ { id: '10', title: 'Pina' } ]
}
}