无依赖关系的 React hook useCallback

问题描述 投票:0回答:2

对于简单的事件处理程序,使用不带 deps 的

useCallback
是否有意义?

例如:

const MyComponent = React.memo(() => {
  const handleClick = useCallback(() => {
    console.log('clicked');
  }, []);

  const handleOtherClick = () => {
    console.log('clicked');
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
      <button onClick={handleOtherClick}>Click me too</button>
    </div>
  );
});

在这种情况下使用

useCallback
有什么优点和缺点?

javascript reactjs react-hooks
2个回答
38
投票

useCallback
的目的并不取决于您是否有依赖关系。这是为了确保引用完整性。以获得更好的性能。如果你需要的话。

因为对于只有函数或函数表达式本身的流程来说,代码可以很好地工作(我的意思是它不需要我们做任何额外的操作来引用实际的 props 等)。所以

useCallback
仅与性能有关。

假设我们渲染纯组件(

React.PureComponent
的实例或包装到
React.memo
中的功能组件)

function MyComponent() {
  const onChangeCallback = ...
  return <SomePureComponent onChange={onChangeCallback} />;
}

这里,如果

onChangeCallback
被声明为函数或箭头表达式,它将在每次渲染时重新创建。所以它的参考意义会有所不同。嵌套的子项每次都会重新渲染,而不必这样做。

另一种情况是将此回调列为其他

useCallback
useMemo
useEffect
中的依赖项。

function MyComponent() {
  const onChangeCallback = ...;
  return <Child onChange={onChangeCallback} />
}

...
function Child({onChange}) {
  useEffect(() => {
    document.body.addEventListener('scroll', onChange);
    return () => document.body.removeEventListener('scroll', onChange);
  }, [onChange]);
}

在这里,我们在没有

onChange
Child
中也会有不同的
useCallback
。因此每次调用父级
useEffect
时都会运行
MyComponent
。虽然我们不需要它这样做。

所以,是的,当您实际上没有任何依赖项时,拥有空的依赖项列表比在没有

useCallback
的情况下声明内联函数更好。


0
投票
export default <A extends unknown[], R>(callback: (...args: A) => R) => {
  const callbackRef = useRef(callback)
  callbackRef.current = callback
  return useCallback((...args: A): R => callbackRef.current(...args), [])
}

Я делаю так, когда нужен независимый 回调

© www.soinside.com 2019 - 2024. All rights reserved.