Отслеживайте одну подпорку с помощью useEffect, которое зависит от нескольких подпорок - PullRequest
1 голос
/ 12 февраля 2020

Существует код, который выглядит следующим образом:

const MyComponent: React.FC<MyComponentProps> = ({
    trackMyChanges,
    iChangeEverySecond
}) => 
{
    // React Hook useEffect has missing dependencies: 'iChangeEverySecond'
    useEffect(() => {
        calculateData(trackMyChanges, iChangeEverySecond);
    }, [trackMyChanges]);   

    return <> ... </>;
}

Код выполняется calculateData в случае изменения пропеллы trackMyChanges. Это работает нормально, но я получаю предупреждение, что отсутствует iChangeEverySecond зависимость. Я не хочу, чтобы крюк работал, потому что iChangeEverySecond был изменен. Как правильно обращаться с этим делом?

Ответы [ 3 ]

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

Вы можете использовать ловушку useCallback для решения этой проблемы:

const calculateData = useCallback(() => {
  console.log(iChangeEverySecond);
}, [iChangeEverySecond]);

useEffect(() => {
  calculateData(trackMyChanges);
}, [trackMyChanges, calculateData]);

Так что каждый раз, когда ваш iChangeEverySecond изменяется, он переопределяет вашу функцию CalculateData как самую последнюю ее версию, но она будет запускаться только когда trackMyChanges изменился.

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

Это потому, что iChangeEverySecond запускается каждый раз, когда trackMyChanges . изменилось. Чтобы справиться с этим сценарием, вы можете добавить ichangeEverySecond в локальное хранилище при его начальной загрузке и затем извлекать его при использовании. Эффект каждый раз, когда trackMyChanges изменяется.

localStorage.setItem ("iChangeEverySecond" ", iChangeEverySecond)

useEffect (() => {

    calculateData(trackMyChanges, localStorage.getItem(iChangeEverySecond));
}, [trackMyChanges]);  
0 голосов
/ 12 февраля 2020

Это из-за объема. Вы понимаете, что массив - это элемент, который помогает useEffect обновить реквизиты или состояние, используемое внутри анонимной функции. В вашем случае iChangeEverySecond - это реквизит, поэтому он «должен», не обязательно быть в массиве, потому что используется внутри функции.

Я оставляю вам полное объяснение, извлеченное из веб-сайта реагирования.

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

Если вы хотите запустить эффект и очистить его только один раз (при монтировании и размонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента. Это говорит React, что ваш эффект не зависит от каких-либо значений из реквизита или состояния, поэтому его не нужно повторно запускать. Это не обрабатывается как особый случай - это следует непосредственно из того, как всегда работает массив зависимостей.

Если вы передадите пустой массив ([]), реквизиты и состояние внутри эффекта всегда будут иметь свои начальные значения. ценности. Хотя передача [] в качестве второго аргумента ближе к знакомой ментальной модели componentDidMount и componentWillUnmount, обычно существуют лучшие решения, позволяющие избежать слишком частого повторного запуска эффектов. Кроме того, не забывайте, что React откладывает запуск useEffect до того, как браузер нарисовал, поэтому выполнение дополнительной работы - не проблема.

Мы рекомендуем использовать правило исчерпывающего ввода-вывода как часть нашего eslint-plugin- пакет реактивных крючков. Он предупреждает, что зависимости указаны неверно, и предлагает исправление.

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