const changedRef = useRef<number>(0);
useEffect(() => {
console.log('<<<<<changedRef>>>>>>', changed);
}, [changedRef.current])
这个时候会报
Mutable values like 'changedRef.current' aren't valid dependencies because mutating them doesn't re-render the component
意思是由于ref不能引起渲染,所以useEffect不能监听它。
那么一些use-deep-compare-effect
下面这样的写法,没问题吗?
import { useRef, useEffect } from 'react';
import _ from 'lodash';
export function useDeepCompareEffect<T>(fn, deps: T) {
// 使用一个数字信号控制是否渲染,简化 react 的计算,也便于调试
let renderRef = useRef<number | any>(0);
let depsRef = useRef<T>(deps);
if (!_.isEqual(deps, depsRef.current)) {
renderRef.current++;
}
depsRef.current = deps;
return useEffect(fn, [renderRef.current]);
}
###- 在eslint看来是有问题的
上述的源码链接能发下?
我理解eslint应该会waring的,除非源码里添加了//eslint-disable-next-line react-hooks/exhaustive-deps
。 useDeepCompareEffect
功能实现上有个疑问,如下:import { useRef, useEffect } from 'react'; import _ from 'lodash'; export function useDeepCompareEffect<T>(fn, deps: T) { // 使用一个数字信号控制是否渲染,简化 react 的计算,也便于调试 let renderRef = useRef<number | any>(0); let depsRef = useRef<T>(deps); if (!_.isEqual(deps, depsRef.current)) { renderRef.current++; + depsRef.current = deps; // 应该只有发生变化时才更新`depsRef.current`吧? } - depsRef.current = deps; return useEffect(fn, [renderRef.current]); }
renderRef.current
为啥不能作为依赖项?
因为只有在执行渲染函数的时候才会计算依赖项表达式的值是否发生变化。依赖项的值发生变化想要执行useEffect
的回调函数的前提条件是依赖项的值变化得能触发re-render
。