Каково намерение использовать хук React's useCallback вместо useEffect? - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь понять, какой вариант использования для использования крюка React useCallback вместо крюка useEffect.

Похоже, что они оба выполняют функцию прослушивания изменений состояния своих входов (примеры взяты из React Docs ):

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

Но хук useEffect дает дополнительное преимущество в очистке ресурсов, которое было бы ранее при использовании componentWillUnmount.

Итак, каков хороший вариант использования useCallback? И что мне здесь не хватает?

1 Ответ

0 голосов
/ 25 января 2019

useEffect имеет очень специфические временные аспекты, которые вы можете прочитать о здесь . Указанная функция будет выполнена после завершения рендеринга и обновления DOM. Это будет происходить после каждого рендеринга, когда изменяется любое из значений, указанных в массиве второго аргумента.

useCallback автоматически ничего не выполняет. Он возвращает функцию, которая может быть выполнена любым кодом, необходимым для ее запуска. Нет прослушивания изменений, которые вызывают выполнение обратного вызова. Значения массива просто контролируют, какой экземпляр функции возвращается. Значения массива не контролируют время выполнения функции.

Ключевым вариантом использования является передача этой функции в качестве опоры дочернему компоненту для использования в качестве обработчика событий. useCallback позволяет вам определить встроенную функцию для использования в качестве обработчика события (таким образом, он имеет доступ к любым другим переменным в контексте, где определена функция) без обратной связи, когда каждый рендер передает уникальную опору ребенку. До тех пор, пока значения в массиве второго аргумента не изменились, будет возвращена та же функция, что и при предыдущем рендеринге. Поэтому, если дочерний компонент является чистым компонентом, он не будет вынужден выполнять повторную визуализацию просто потому, что всегда получает уникальную функцию-обработчик событий.

без useCallback

const Parent = ()=> {
   const [a, setA] = useState(null);
   const eventHandler = ()=> {
      // every render creates a unique instance of eventHandler
      // even though it always does the same thing so long as 'a' hasn't changed
      doSomethingWithA(a);
   }
   return <Child onClick={eventHandler}/>
}

с useCallback

const Parent = ()=> {
   const [a, setA] = useState(null);
   const eventHandler = useCallback(()=> {
      // A unique function instance is passed in to useCallback on every render, but
      // eventHandler will be set to the first instance of this function
      // (i.e. potentially an instance of the function that was passed to useCallback
      // on a previous rendering) that was passed to useCallback
      // for the current value of 'a'.
      doSomethingWithA(a);
   }, [a]);
   return <Child onClick={eventHandler}/>
}

Эта статья предоставляет немного больше подробностей, чем документы React, по варианту использования для useCallback и другим хукам.

...