实现编辑内容的撤销、恢复功能 (react hook)
useEditHistory.ts
import {useCallback, useState} from 'react';
const useEditHistory = <T>({
initialHistory,
onHistoryCurrentChange,
} : {
/** 初始化数据 */
initialHistory: T;
/** 触发当前编辑区域数据变化 */
onHistoryCurrentChange: (current: T) => void;
}) => {
const [history, setHistory] = useState<{past: T[]; current: T; future: T[]}>({
past: [],
current: [],
future: []
});
const resetHistory = useCallback((initialHistory: T) => {
setHistory({
past: [],
current: initialHistory,
future: [],
})
}, []);
const recordHistory = useCallback((current: T) => {
setHistory(history => {
if (history.current === current) return history;
return {
past: [...history.past, history.current],
current,
future: [],
}
})
}, []);
// 撤销
const undo = useCallback((current: T) => {
setHistory(history => {
if (!history.past.length) return history;
const current = history.past[history.past.length - 1];
onHistoryCurrentChange(current);
return {
past: history.past.slice(0, -1),
current,
future: [...history.future, history.current],
};
});
}, [onHistoryCurrentChange]);
// 恢复
const redo = useCallback((current: T) => {
setHistory(history => {
if (!history.future.length) return history;
const current = history.future[history.future.length - 1];
onHistoryCurrentChange(current);
return {
past: [...history.past, history.current],
current,
future: history.future.slice(0, -1),
};
});
}, [onHistoryCurrentChange]);
return {resetHistory, recordHistory, history, setHistory, undo, redo};
}
export default useEditHistory;