搜索

首页  >  问答  >  正文

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

<p>所以据说,useCallback可以缓存一个函数,我认为意图是为了使代码运行更快。</p> <p>例如,如果我有:</p> <pre class="brush:js;toolbar:false;"> const handleChange = (ev) => { setMsg(ev.target.value); }; </pre> <p>我也可以将其改为:</p> <pre class="brush:js;toolbar:false;"> const handleChange = useCallback((ev) => { setMsg(ev.target.value); }, []); </pre> <p>这样现在函数被缓存了。然而,这个函数不管怎样都需要在组件重新渲染时创建吗?</p> <p>为了测试它,我将其改为IIFE,这样函数就从中输出出来,它会打印出函数正在被输出。</p> <p>请参见: https://codesandbox.io/s/jolly-nightingale-zxqp8k</p> <p>所以每当你在输入框中输入内容时,都会输出一个新的函数,如控制台所示。这意味着,IIFE每次都会执行,这也意味着,即使它不是IIFE,函数字面量也会每次都被转换为函数对象。那么这如何帮助代码运行更快呢?</p>
P粉924915787P粉924915787465 天前491

全部回复(1)我来回复

  • P粉834840856

    P粉8348408562023-08-19 00:29:53

    是的,这是正确的。每次渲染都会创建一个新的函数,然后新的函数会被缓存的函数所替代。

    加速并不是因为跳过了创建函数的步骤,而是因为其他代码能够跳过它们自己的工作。这是因为如果它们每次都传递相同的函数,它们就知道没有相关的内容发生了变化。

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

    useEffect(() => {
      // ... 使用handleChange做一些事情
    }, [handleChange]);

    或者,如果handleChange作为prop传递给一个组件,并且该组件想要使用React.memo跳过渲染。只有在props没有改变时,才能跳过渲染:

    const Parent = () => {
      const handleChange = useCallback((ev) => {
        setMsg(ev.target.value);
      }, []);
      return <Child handleChange={handleChange}/>
    }
    
    const Child = React.memo(({ handleChange }) => {
      // ... 使用handleChange做一些事情
    })

    回复
    0
  • 取消回复