useCallback 如何帮助代码运行得更快?

Ste*_*uss 1 reactjs react-hooks

所以据说useCallback可以缓存一个函数,我认为目的是让代码运行得更快。

例如,如果我有:

  const handleChange = (ev) => {
    setMsg(ev.target.value);
  };
Run Code Online (Sandbox Code Playgroud)

我也可以将其更改为:

  const handleChange = useCallback((ev) => {
    setMsg(ev.target.value);
  }, []);
Run Code Online (Sandbox Code Playgroud)

这样现在函数就被缓存了。但是,每次重新渲染组件时是否都需要创建此函数?

为了测试它,我将其更改为 IIFE,以便从其中吐出该函数,并且它会打印出该函数正在吐出。

请参阅: https ://codesandbox.io/s/jolly-nightingale-zxqp8k

因此,每次当您在输入字段中输入内容时,都会输出一个新函数,如控制台中所示。因此,这意味着 IIFE 每次都会以任何方式执行,这意味着即使它不是 IIFE,函数文字每次也会被制作成函数对象。那么这如何帮助代码运行得更快呢?

Nic*_*wer 5

但是,每次重新渲染组件时是否都需要创建此函数?

对,那是正确的。每次渲染时都会创建一个新函数,然后新函数将被丢弃,取而代之的是缓存的函数。

速度的提高并不是来自跳过创建函数。相反,它来自于能够跳过其工作的其他代码片段。发生这种情况是因为如果他们每次都传递相同的函数,他们就可以知道没有任何相关的变化。

例如,如果您需要传递handleChange到 useEffect 的依赖数组,那么每次传递一个稳定的引用非常重要,否则效果将在每次渲染时重新运行:

useEffect(() => {
  // ... do something with handleChange
}, [handleChange]);
Run Code Online (Sandbox Code Playgroud)

或者,如果handleChange作为 prop 传递给组件,并且该组件想要跳过使用React.memo. 仅当 props 不改变时才能跳过渲染:

const Parent = () => {
  const handleChange = useCallback((ev) => {
    setMsg(ev.target.value);
  }, []);
  return <Child handleChange={handleChange}/>
}

const Child = React.memo(({ handleChange }) => {
  // ... do something with handleChange
})
Run Code Online (Sandbox Code Playgroud)