Как избежать бесконечного l oop с useEffect в этом случае? (Реагировать) - PullRequest
0 голосов
/ 01 августа 2020

Итак, я хочу вызывать run() всякий раз, когда a (в состоянии компонента) изменяется.

run() устанавливает значение другой переменной состояния, b.

  import {computeWithB} from '../helpers/compute'

  const [a, setA] = useState()
  const [b, setB] = useState()

  const run = () => {
    result = computeWithB(b)
    setB(result)
  }

  useEffect(() => {
    run();
  }, [a, run]);

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

В настоящее время бесконечное l oop результатов.

Я не могу переместить run () в обратный вызов useEffect, потому что мне также нужно иметь возможность вызывать run () из любого места в компоненте.

Если я это сделаю

const run = useCallback(() => {
  result = computeWithB(b)
    setB(result)
}, [b]);

бесконечное l oop в результате установки b, пока это зависимость.

Как мне вызвать run() один раз каждый раз, когда a изменяется?

Буду признателен за любой совет!

1 Ответ

2 голосов
/ 01 августа 2020

Функция run в useEffect устанавливает состояние, которое запускает повторную визуализацию. Теперь, поскольку повторный рендеринг вызывает создание новой ссылки на функцию запуска, а run используется как зависимость для useEffect, useEffect вызывается снова, вызывая бесконечное l oop

Вы можете использовать useCallback для функции запуска, чтобы избежать новой ссылки на каждый рендер и использовать обновление функционального состояния внутри него, например

 import {computeWithB} from '../helpers/compute'

  const [a, setA] = useState()
  const [b, setB] = useState()

  const run = useCallback(() => {
    setB(prevB => computeWithB(prevB))
  }, [setB])

  useEffect(() => {
    run();
  }, [a, run]);
...