В чем разница между useCallback и useMemo - PullRequest
0 голосов
/ 17 февраля 2020

Может быть, я что-то неправильно понял, но useCallback Hook запускается каждый раз, когда происходит повторный рендеринг.

Я передал входные данные - в качестве второго аргумента для использованияCallback - неизменяемые константы - но возвращенный запомненный обратный вызов по-прежнему запускает мой дорогостоящие вычисления при каждом рендеринге (я уверен - вы сами можете проверить это во фрагменте ниже).

Я изменил useCallback на useMemo - и useMemo работает как положено - запускается при изменении переданных входных данных. И действительно запоминает дорогие расчеты.

Живой пример:

'use strict';

const { useState, useCallback, useMemo } = React;

const neverChange = 'I never change';
const oneSecond = 1000;

function App() {
  const [second, setSecond] = useState(0);
  
  // This ? expensive function executes everytime when render happens:
  const calcCallback = useCallback(() => expensiveCalc('useCallback'), [neverChange]);
  const computedCallback = calcCallback();
  
  // This ? executes once
  const computedMemo = useMemo(() => expensiveCalc('useMemo'), [neverChange]);
  
  setTimeout(() => setSecond(second + 1), oneSecond);
  
  return `
    useCallback: ${computedCallback} times |
    useMemo: ${computedMemo} |
    App lifetime: ${second}sec.
  `;
}

const tenThousand = 10 * 1000;
let expensiveCalcExecutedTimes = { 'useCallback': 0, 'useMemo': 0 };

function expensiveCalc(hook) {
  let i = 0;
  while (i < tenThousand) i++;
  
  return ++expensiveCalcExecutedTimes[hook];
}


ReactDOM.render(
  React.createElement(App),
  document.querySelector('#app')
);
<h1>useCallback vs useMemo:</h1>
<div id="app">Loading...</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

useMemo предназначен для запуска функции и возврата значения при визуализации компонента (при условии, что одна из зависимостей изменилась). useCallback предназначен для возврата (запомненной) функции во время рендеринга, но на самом деле пока не вызывает функцию; как правило, вы просто передаете эту функцию параметру onClick или что-то в этом роде.

Вы можете использовать их взаимозаменяемо при правильном вызове, например, имея useMemo return, функция эквивалентна useCallback, или используя useCallback, а затем вызов возвращаемой функции аналогичен useMemo

0 голосов
/ 17 февраля 2020

useMemo() заставляет функцию работать только при изменении входа. В противном случае он возвращает запомненный (кэшированный) результат.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...