Когда использовать useCallback, useMemo и useEffect - PullRequest
16 голосов
/ 06 июля 2019

В чем основное различие между useCallback, useMemo и useEffect. Приведите примеры использования useCallback, useMemo и useEffect.

Ответы [ 2 ]

9 голосов
/ 06 июля 2019

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

function Example() {
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'))
<script src="https://unpkg.com/react@16.8.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.8.0/umd/react-dom.development.js"></script>

<div id="root"></div>

Пример выше взят из документации React .Вы можете видеть, что каждый раз, когда вы нажимаете кнопку, это вызывает обновление поля подсчета (с помощью setCount ()), а затем эффект, зависящий от переменной count, запускает обновление заголовка страницы.


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

function ExampleChild({ callbackFunction }) {
  const [value, setValue] = React.useState(0);

  React.useEffect(() => {
    setValue(value + 1)
  }, [callbackFunction]);

  return (<p>Child: {value}</p>);
}

function ExampleParent() {
  const [count, setCount] = React.useState(0);
  const [another, setAnother] = React.useState(0);
  
  const countCallback = React.useCallback(() => {
    return count;
  }, [count]);
  
  return (
    <div>
      <ExampleChild callbackFunction={countCallback} />
      <button onClick={() => setCount(count + 1)}>
        Change callback
      </button>
      
      <button onClick={() => setAnother(another + 1)}>
        Do not change callback
      </button>
    </div>
  )
}

ReactDOM.render(<ExampleParent />, document.getElementById('root'));
<script src="https://unpkg.com/react@16.8.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.8.0/umd/react-dom.development.js"></script>

<div id="root"></div>

useMemo() вернет значение памятное , которое является результатом переданного параметра.Это означает, что useMemo() сделает вычисление для некоторого параметра один раз, а затем вернет тот же результат для того же параметра из кэша.

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

function ExampleChild({ value }) {
   const [childValue, setChildValue] = React.useState(0);

   React.useEffect(() => {
     setChildValue(childValue + 1);
   }, [value])

   return <p>Child value: {childValue}</p>;
}

function ExampleParent() {
  const [value, setValue] = React.useState(0);
  const heavyProcessing = () => {
    // Do some heavy processing with the parameter
    console.log(`Cached memo: ${value}`);
    return value;
  };

  const memoizedResult = React.useMemo(heavyProcessing, [value]);
  
  return (
    <div>
      <ExampleChild value={memoizedResult} />
      <button onClick={() => setValue(value + 1)}>
        Change memo
      </button>
    </div>
  )
}

ReactDOM.render(<ExampleParent />, document.getElementById('root'));
<script src="https://unpkg.com/react@16.8.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.8.0/umd/react-dom.development.js"></script>

<div id="root"></div>
4 голосов
/ 06 июля 2019

Краткое объяснение.

useEffect

Это альтернатива для компонентов класса lifecicle (componentDidMount, componentWillUnmount, componentDidUpdate, ...), и вы также можетеиспользуйте его как побочный эффект, основанный на некоторых зависимостях, «когда изменяются некоторые переменные, сделайте это».

useCallback

При каждом рендеринге все, что находится внутри компонента (функции), запускается снова, поэтому, если какой-либо дочерний компонент зависит от какой-либо функции от родительского компонента, дочерний компонент будет перерисовываться каждый раз, когда перерисовывается родительский компонент, даже если эта функция «не изменяется» (ссылка изменяется, но что будет делать функция:t).
Он используется для оптимизации, избегая ненужных дочерних рендеров, заставляя функцию изменять ссылку только при изменении некоторых зависимостей.Вы должны использовать его, когда функция является зависимостью от побочного эффекта, например useEffect.

useMemo

. Она будет выполняться при каждом рендеринге, но с кэшированными значениями.Он будет использовать новые значения только при изменении определенных зависимостей.Он используется для оптимизации, когда у вас есть дорогие вычисления, которые вы. Вот также хороший ответ, который объясняет это .

...