如何重构自定义useTime Hook以支持在方法内调用?
重构方案
方案一:改为普通工具函数
既然要在方法/函数内调用,直接把它做成不依赖React Hook的普通工具函数,返回定时器ID方便手动管理:
const delayExecute = (callback, timeout = 1000) => { const timer = setTimeout(() => { callback(); }, timeout); return timer; };
使用示例:
{ clear: () => { // 调用普通函数,如需提前取消可保存timerId后执行clearTimeout const timerId = delayExecute(() => console.log('close'), 6000); // 示例:3秒后取消定时器 // setTimeout(() => clearTimeout(timerId), 3000); }, }
方案二:Hook返回可触发延迟执行的函数
如果需要借助React生命周期自动清理未执行的定时器(比如组件卸载时取消任务),可以重构Hook,让它返回一个能触发延迟执行的函数,同时自动管理定时器的清理:
const useDelayExecutor = () => { const timersRef = useRef([]); // 组件卸载时清理所有未完成的定时器 useEffect(() => { return () => { timersRef.current.forEach(timerId => clearTimeout(timerId)); }; }, []); const execute = (callback, timeout = 1000) => { const timerId = setTimeout(() => { callback(); // 执行完成后从列表中移除该定时器ID timersRef.current = timersRef.current.filter(id => id !== timerId); }, timeout); timersRef.current.push(timerId); return timerId; }; return execute; };
使用示例:
// 必须在组件顶层调用Hook const executeDelay = useDelayExecutor(); // 在方法内调用返回的函数 { clear: () => { executeDelay(() => console.log('close'), 6000); }, }
原Hook无法在方法内调用的原因
React Hook必须遵守两条核心规则:
- 只能在组件顶层或自定义Hook顶层调用
- 不能在条件判断、循环、嵌套函数(比如你的
clear方法)内调用
原useTime内部使用了useEffect(属于Hook),在方法内调用就违反了上述规则,因此会报错。
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

