react hooks 如何有效的解决闭包问题?

请教一下,闭包在 react 中不注意就会产生,尤其是传递 方法的时候,有什么解决闭包的方法吗?

阅读 2.5k
4 个回答

1.用依赖数组:在 useEffect 或者 useCallback 里,可以通过提供一个依赖数组来通知 React 哪些变量的变化应该触发函数的重新执行。

useEffect(() => {
  // 函数会在 count 变化时重新执行
  console.log(count);
}, [count]);

2.用 ref 在整个组件生命周期内保持不变,但它的 current 属性可以存储可变的值。

const countRef = useRef(count);
countRef.current = count;

useEffect(() => {
  const id = setInterval(() => {
    console.log(countRef.current); //引用最新的 count
  }, 1000);
  return () => clearInterval(id);
}, []); // 空依赖数组,函数只在组件挂载时执行一次

3。用函数式更新:

const [count, setCount] = useState(0);

// 错误的更新方式,可能会引用旧的 count
const increment = () => setCount(count + 1);

// 正确的更新方式,总是基于最新的 count
const increment = () => setCount(prevCount => prevCount + 1);

没有踩过这个坑的。不算使用过react。

针对函数,通过 useRef 做一次记录,以保证在任何地方都能访问到最新的函数。

const fnRef = useRef(fn);
fnRef.current = fn;

代码如下:

function useMemoizedFn<T extends noop>(fn: T) {
  const fnRef = useRef<T>(fn);
  fnRef.current = useMemo(() => fn, [fn]);

  const memoizedFn = useRef<PickFunction<T>>();
  if (!memoizedFn.current) {
    memoizedFn.current = function (this, ...args) {
      return fnRef.current.apply(this, args);
    };
  }

  return memoizedFn.current as T;
}
  1. 过期闭包只能通过给 hooks 增加正确的依赖项来解决
  2. 对于函数可以基于 useCallback 封装一下,让外部调用的时候可以不用关心依赖项的问题,大体上可以这样实现:

    import { useCallback, useRef } from 'react';
    
    export default function useEvent(handler) {
     const ref = useRef(handler);
    
     ref.current = handler;
    
     return useCallback((...args) => {
         ref.current?.(...args);
     }, []);
    }
    

    利用 ref 实现一个动态的函数引用

logo
Microsoft
子站问答
访问
宣传栏