import { useState, useRef, useCallback, useEffect } from "react"; type ChangeAction = S | ((prevValue: S) => S); export interface ChangeHandler { (value: T, ...args: P); } export function useDefault( value: T | undefined, defaultValue: T | undefined, onChange: ChangeHandler | undefined ): [T, ChangeHandler, P>] { const isControlledRef = useRef(false); const valueRef = useRef(defaultValue); const [internalValue, setInternalValue] = useState(defaultValue); useEffect(() => { if (isControlledRef.current) { valueRef.current = value; } }, [value]); const handleInternalChange = useCallback>( (newValue, ...args) => { // 回调形式更新 if (typeof newValue === "function") { // eslint-disable-next-line no-param-reassign newValue = newValue(valueRef.current); } setInternalValue(newValue); valueRef.current = newValue; if (typeof onChange === "function") { onChange(newValue, ...args); } }, [onChange] ); const handleChange = useCallback>( (newValue, ...args) => { // 回调形式更新 if (typeof newValue === "function") { // eslint-disable-next-line no-param-reassign newValue = newValue(valueRef.current); } if (typeof onChange === "function") { onChange(newValue, ...args); } }, [onChange] ); // 受控模式 if (isControlledRef.current || typeof value !== "undefined") { isControlledRef.current = true; return [value, handleChange]; } // 非受控模式 return [internalValue, handleInternalChange]; }