Проблема с простым примером использования React HooksCallback

Просто не добавляйте к классу методы public mutator (setter).

2
задан Peter Kellner 28 February 2019 в 19:10
поделиться

2 ответа

У вас есть дополнительные { } после =>, создавая таким образом блок и область, просто удалите их и тоже ;, так как это делает это оператором. В противном случае передайте ему аргументы, используйте это

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

В нем говорится undefined, потому что область действия => { } не получает a,b. Надеюсь, это поможет.

0
ответ дан its4zahoor 28 February 2019 в 19:10
поделиться

Цель useCallback - иметь возможность использовать реквизит или состояние, которые находятся в текущей области видимости и которые могут измениться при повторном рендеринге. Затем массив зависимостей сообщает React, когда вам нужна новая версия обратного вызова. Если вы пытаетесь запоминать дорогостоящие вычисления, вам нужно вместо этого использовать useMemo.

Пример ниже демонстрирует различия между useCallback и useMemo и последствия их неиспользования. В этом примере я использую React.memo для предотвращения повторного рендеринга Child, если только его реквизиты или состояние не изменятся. Это позволяет увидеть преимущества useCallback. Теперь, если Child получит новый onClick реквизит, это вызовет повторную визуализацию.

Дочерний элемент 1 получает незарегистрированный обратный вызов onClick, поэтому всякий раз, когда родительский компонент выполняет повторную визуализацию, дочерний элемент 1 всегда получает новую функцию onClick, поэтому он вынужден выполнять повторную визуализацию.

Ребенок 2 использует запомненный обратный вызов onClick, возвращенный из useCallback, а ребенок 3 использует эквивалент через useMemo, чтобы продемонстрировать значение

useCallback (fn, input) эквивалентно useMemo (() => fn, input)

Для дочерних элементов 2 и 3 обратный вызов по-прежнему выполняется каждый раз, когда вы нажимаете дочерний элемент 2 или 3, useCallback просто гарантирует, что один и тот же версия функции onClick передается, когда зависимости не изменились.

Следующая часть дисплея помогает указать, что происходит:

nonMemoizedCallback === memoizedCallback: false | true

Отдельно я Отображаю somethingExpensiveBasedOnA и запомнили версию, используя useMemo. В демонстрационных целях я использую неверный массив зависимостей (я намеренно пропустил b), чтобы вы могли видеть, что запомненная версия не изменяется при изменении b, но меняется при изменении a. Незамеченная версия изменяется всякий раз, когда изменяется a или b.

import ReactDOM from "react-dom";

import React, {
  useRef,
  useMemo,
  useEffect,
  useState,
  useCallback
} from "react";

const Child = React.memo(({ onClick, suffix }) => {
  const numRendersRef = useRef(1);
  useEffect(() => {
    numRendersRef.current++;
  });

  return (
    <div onClick={() => onClick(suffix)}>
      Click Me to log a and {suffix} and change b. Number of Renders:{" "}
      {numRendersRef.current}
    </div>
  );
});
function App(props) {
  const [a, setA] = useState("aaa");
  const [b, setB] = useState("bbb");

  const computeSomethingExpensiveBasedOnA = () => {
    console.log("recomputing expensive thing", a);
    return a + b;
  };
  const somethingExpensiveBasedOnA = computeSomethingExpensiveBasedOnA();
  const memoizedSomethingExpensiveBasedOnA = useMemo(
    () => computeSomethingExpensiveBasedOnA(),
    [a]
  );
  const nonMemoizedCallback = suffix => {
    console.log(a + suffix);
    setB(prev => prev + "b");
  };
  const memoizedCallback = useCallback(nonMemoizedCallback, [a]);
  const memoizedCallbackUsingMemo = useMemo(() => nonMemoizedCallback, [a]);
  return (
    <div>
      A: {a}
      <br />
      B: {b}
      <br />
      nonMemoizedCallback === memoizedCallback:{" "}
      {String(nonMemoizedCallback === memoizedCallback)}
      <br />
      somethingExpensiveBasedOnA: {somethingExpensiveBasedOnA}
      <br />
      memoizedSomethingExpensiveBasedOnA: {memoizedSomethingExpensiveBasedOnA}
      <br />
      <br />
      <div onClick={() => setA(a + "a")}>Click Me to change a</div>
      <br />
      <Child onClick={nonMemoizedCallback} suffix="1" />
      <Child onClick={memoizedCallback} suffix="2" />
      <Child onClick={memoizedCallbackUsingMemo} suffix="3" />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit useCallback and useMemo

Вот связанный ответ: React Hooks useCallback заставляет дочерний процесс перерисовывать

0
ответ дан Ryan Cogswell 28 February 2019 в 19:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: