反应挂钩useCallback没有依赖

Lio*_*rez 1 javascript reactjs react-hooks

useCallback没有deps的情况下将其用于简单事件处理程序是否有意义?

例如:

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>
  );
});
Run Code Online (Sandbox Code Playgroud)

useCallback在这种情况下使用的利弊是什么?

sky*_*yer 5

的目的useCallback不取决于您是否具有依赖项。这是为了确保参照完整性。为了获得更好的性能。如果需要的话。

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

假设我们渲染了纯组件(React.PureComponent包装为的实例或功能组件React.memo

function MyComponent() {
  const onChangeCallback = ...
  return <SomePureComponent onChange={onChangeCallback} />;
}
Run Code Online (Sandbox Code Playgroud)

在这里,如果onChangeCallback仅声明为函数或箭头表达式,则会在每个渲染器上重新创建它。因此,它在参考上会有所不同。嵌套子项每次都将重新渲染,而不必这样做。

另一种情况是上市这个回调是在其他的依赖useCallbackuseMemouseEffect

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

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

在这里,onChangeChild没有的情况下,我们也会有不同的参照useCallback。因此,useEffect将在每次MyComponent调用父对象时运行。虽然我们不需要这样做。

因此,是的,在实际上没有任何依赖项的情况下使用空的依赖项列表会比根本不声明函数内联更好useCallback

PS,如果您的子组件不是真的正确并且有内存泄漏(例如useEffect不返回清除功能),则useCallback实际上可能会部分减轻后果。当然,这不是目标(编写有内存泄漏的组件),但对我来说,useCallback即使是简单的处理程序,也要使用0.5分