创建一个历史记录栈past
,和一个撤销过的栈future
,,在每次操作store的时候,将当前的store的数据,存入历史记录栈past
中,,
如果是撤销操作,,就从这个历史栈中取最后面那个数据,,并且将这个数据push到future栈中,,,
如果是恢复操作,,就去future栈中的最后的那一个数据,用来恢复原数据
import {configureStore, createSlice} from "@reduxjs/toolkit";
export interface HistoryState<T>{
past: T[], // 历史状态栈
present: T, // 当前状态
future: T[] // 重做栈
}
export interface CounterState{
value:number
}
// 初始状态
const initialCounterState : CounterState = {value:0}
// 初始化历史状态
const initialHistoryState:HistoryState<CounterState> = {
past:[],
present: initialCounterState,
future:[]
}
const counterSlice = createSlice({
name:"counter",
initialState:initialHistoryState,
reducers:{
// 常规操作,,, 自动记录历史
increment(state){
const {past,present,future} = state
console.log(past,present,future,"11")
return{
past:[state.present,...state.past].slice(0,20), // 保留最后20条
present:{value:state.present.value +1},
future:[]
}
},
// 撤销
undo(state){
if (state.past.length === 0){
return state
}
// var [newPresent,...[]] = state.past.slice(-1);
// var newPast = state.past.slice(0,state.past.length-1);
// 新增的时候,从最前面添加,,,
var [newPresent,...newPast] = state.past
return {
past:newPast,
present:newPresent,
future:[state.present,...state.future] // 新增的时候也是第一个
}
},
// 重做
redo(state){
if (state.future.length === 0){
return
}
// 取出的时候是第一个
const [newPresent,...newFuture] = state.future
return {
past:[state.present,...state.past],
present:newPresent,
future:newFuture
}
},
// 重置,清空历史
reset(state){
return{
past:[],
present: initialCounterState,
future: state.future
}
}
}
})
export const {reset,increment,redo,undo} = counterSlice.actions
export default counterSlice.reducer
<div>
{present.value}
<button onClick={handleAdd} className="px-2 py-2 bg-yellow-200">+1</button>
<button onClick={handleUndo}>撤销</button>
<button onClick={handleRedo}>重做</button>
</div>
function handleAdd(){
dispatch(increment())
}
function handleUndo(){
dispatch(undo())
}
function handleRedo(){
dispatch(redo())
}
有一个现成的库redux-undo