背景
react-compound-timer
库的useTimer Hook实现
有这么段代码:
const timer = useMemo( () => new TimerModel({ initialTime, direction, timeToUpdate, lastUnit, checkpoints, onChange: (timerValue: TimerValue) => setTimerValues(state => ({ ...state, ...timerValue })), }), [], );
useMemo
的依赖是空数组,所以变量timer
在组件生命周期里都不会变动,有点相似实例变量。然而Hooks里实现实例变量不是useRef
的专长吗?这里为啥应用的是useMemo
?
useMemo
代替useRef
?
如果只是实现实例变量,那么 useMemo
是否能够代替useRef
?如:
const ref = useRef(null);const ref2 = useMemo(() => { current: null }, []);
应用上没问题,但不是最佳实际。
useMemo
会跟踪依赖项,并且通过比拟依赖项是否发生变化决定是否从新执行函数。即便依赖项是个空数组,然而外部还是会做局部额定的逻辑。所以性能上比useRef
要差。- React对
useMemo
定位只是用于性能优化,并不保障在依赖项不变时,就肯定不会从新执行函数。
- How to memoize calculations?里提到:
You may rely on useMemo as a performance optimization, not as a semantic guarantee.
- Dan在twiter:A few small updates to Hooks FAQ based on common questions.里也强调:
useMemo() is a hint — not a guarantee. React may still choose to “forget” some memoized values to reclaim memory. Don’t rely on it for correctness
所以对于那些确定不须要从新计算的值,则优先应用useRef
,不要应用useMemo
。
参考
整顿自gitHub笔记:useMemo代替useRef ?!