@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* 撤销/重做 Hook — 通用历史栈管理
|
||||
* 支持任意状态的快照式 undo/redo
|
||||
*/
|
||||
import { useState, useCallback, useRef } from "react"
|
||||
|
||||
const MAX_HISTORY = 50
|
||||
|
||||
export function useUndoRedo<T>(initialState: T) {
|
||||
const [present, setPresent] = useState<T>(initialState)
|
||||
const pastRef = useRef<T[]>([])
|
||||
const futureRef = useRef<T[]>([])
|
||||
const [canUndo, setCanUndo] = useState(false)
|
||||
const [canRedo, setCanRedo] = useState(false)
|
||||
|
||||
const set = useCallback((next: T | ((prev: T) => T)) => {
|
||||
setPresent((curr) => {
|
||||
const resolved = typeof next === "function" ? (next as (p: T) => T)(curr) : next
|
||||
pastRef.current = [...pastRef.current.slice(-(MAX_HISTORY - 1)), curr]
|
||||
futureRef.current = []
|
||||
setCanUndo(true)
|
||||
setCanRedo(false)
|
||||
return resolved
|
||||
})
|
||||
}, [])
|
||||
|
||||
const undo = useCallback(() => {
|
||||
setPresent((curr) => {
|
||||
const past = pastRef.current
|
||||
if (past.length === 0) return curr
|
||||
const prev = past[past.length - 1]
|
||||
pastRef.current = past.slice(0, -1)
|
||||
futureRef.current = [curr, ...futureRef.current]
|
||||
setCanUndo(pastRef.current.length > 0)
|
||||
setCanRedo(true)
|
||||
return prev
|
||||
})
|
||||
}, [])
|
||||
|
||||
const redo = useCallback(() => {
|
||||
setPresent((curr) => {
|
||||
const future = futureRef.current
|
||||
if (future.length === 0) return curr
|
||||
const next = future[0]
|
||||
futureRef.current = future.slice(1)
|
||||
pastRef.current = [...pastRef.current, curr]
|
||||
setCanUndo(true)
|
||||
setCanRedo(futureRef.current.length > 0)
|
||||
return next
|
||||
})
|
||||
}, [])
|
||||
|
||||
const reset = useCallback((state: T) => {
|
||||
pastRef.current = []
|
||||
futureRef.current = []
|
||||
setPresent(state)
|
||||
setCanUndo(false)
|
||||
setCanRedo(false)
|
||||
}, [])
|
||||
|
||||
return { state: present, set, undo, redo, canUndo, canRedo, reset }
|
||||
}
|
||||
Reference in New Issue
Block a user