我应该在useCallback中包装组件中定义的所有函数吗?

时间:2019-07-23 04:10:58

标签: reactjs react-hooks usecallback

据我所知,每当重新渲染React的功能组件中定义的函数时,就会重新生成该函数。由于useCallback可以由特定的依赖项触发,因此可以防止不必要地重新生成这些函数。我应该将它们包装在useCallback中,并传递相关的依赖关系吗?

import React from 'react'

const Comp = () => {
   const fn1 = useCallback(
     ()=>{
      // do something
   }, [dependency1])

   const fn2 = useCallback(
     ()=>{
      // do something
   }, [dependency2])

   return (
      //something
   )
}

2 个答案:

答案 0 :(得分:2)

useCallback将有助于避免在重新渲染功能组件时避免功能的重新生成。但是,功能的重现不会带来太大的性能差异。

在以下情况下,最好使用useCallback

  1. 如果将函数作为道具传递给子组件,并且子组件通常不需要重新渲染,除非在更改某些道具时,useCallback可能会阻止某些重新渲染。但是,如果您声明的状态很复杂,并且需要将多个此类函数作为道具传递给子级,则最好转移到useReducer而不是useState并将dispatch方法传递给子级组件

  2. 您正在指定一个函数作为对useEffect的依赖。在这种情况下,您必须确保不会在每个渲染器上重新创建该函数,否则将在每个渲染器上触发useEffect

必须明智地而不是一味地做出使用useCallback的决定,因为您可能会过度使用useCallback所提供的优势,并最终降低性能,因为useCallback还会记住函数和经常变化的依赖关系可能仍然需要重新创建该函数。

答案 1 :(得分:1)

功能组件有两种方法,

  1. 渲染中的箭头功能
  2. 构造函数绑定(ES2015)

如果我们使用挂钩翻译两种方法,则它们是等效的(某种):

1。渲染中的箭头功能->未存储的回调

function Foo1() {
    const handleClick = () => {
        console.log('Click happened');
    }
    return <Button onClick={handleClick}>Click Me</Button>; 
 }

2。绑定到构造函数中(ES2015)->记忆化回调

function Foo1() {
    const memoizedHandleClick = useCallback(
          () => console.log('Click happened'), [],
    ); // Tells React to memoize regardless of arguments.
    return <Button onClick={memoizedHandleClick}>Click Me</Button>;
}

第一种方法是在每次调用功能组件时创建回调,但是第二种方法是,React为您记住回调函数,并且不会多次创建该回调。

在大多数情况下,第一种方法很好。如React docs所述:

  

可以在渲染方法中使用箭头功能吗?一般来说,   是的,没关系,并且通常是将参数传递给的最简单方法   回调函数。