redux-undo 无缝接入 reducer

681 阅读2分钟

实现撤销和重做功能一定需要 redux-undo 吗?不一定,redux 文档中提到,用 redux 轻而易举地实现撤销历史。

但是,有没有一个库能帮助我们实现可撤销功能,而不是由我们自己编写呢?当然有!来看看 Redux Undo,它可以为你的 Redux 状态树中的任何部分提供撤销和重做功能。

www.redux.org.cn/docs/recipe…

如何在现有的代码中接入 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' } ]
  }
}