В React Hook useEffect отсутствует массив зависимостей - PullRequest
1 голос
/ 27 июня 2019

Я использую базу данных Firebase для хранения данных и монтирую их с помощью ловушки useEffect.Но он предупреждает меня о пропущенных массивах зависимостей.

Всякий раз, когда я передаю зависимости, она входит в бесконечный цикл

const Channels = props => {
  const [channels, setChannels] = useState([]);
  const [firstLoad, setFirstLoad] = useState(false);

  useEffect(() => {
    let loadedChannels = [];

    firebase
      .database()
      .ref("channels")
      .on("child_added", snap => {
        loadedChannels.push(snap.val());
        setChannels(channels.concat(loadedChannels));
        setFirstLoad(true);
      });
  }, []);
}

Ответы [ 2 ]

2 голосов
/ 27 июня 2019

Редактировать: Глядя на это снова, причина того, что вы получаете эту ошибку, заключается в том, что вы закрываете начальное значение channels, когда ваш useEffect() запускается в первый раз. Так что channels действительно должно быть в вашем массиве зависимостей, потому что, когда это значение изменится, вы захотите, чтобы с тех пор новое значение отражалось в обновлениях состояния. Вы пытаетесь обойти это с массивом loadedChannels, который является странным анти-паттерном.

Я бы порекомендовал вам настроить его на что-то вроде этого. Обратите внимание, как setChannels теперь вызывается с функцией, которая принимает в качестве аргумента фактическое актуальное значение , равное channels, и позволяет обновлять значение без его устаревания из-за закрытия.

Также обратите внимание, как функция useEffect() возвращает другую функцию , которая удаляет прослушиватель событий Firebase при размонтировании компонента!

const Channels = props => {
  const [channels, setChannels] = useState([]);
  const [firstLoad, setFirstLoad] = useState(false);

  useEffect(() => {
    function onFirebaseUpdate(snap) {
      setChannels((previousChannelsValue) => {
        return previousChannelsValue.concat(snap.val())
      });
      setFirstLoad(true);
    }

    firebase
      .database()
      .ref("channels")
      .on("child_added", onFirebaseUpdate);

    // You'll want to remove this listener when the component unmounts...
    return function() {
      firebase
        .database()
        .ref("channels")
        .off("child_added", onFirebaseUpdate);
    }
  }, []);
}

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

0 голосов
/ 27 июня 2019

Как насчет размещения каналов в deps []?

...