cleanup () не работает в useEffect () с Firebase Firestore onSnapshot - PullRequest
1 голос
/ 22 января 2020

У меня есть проект React, который перечисляет данные из Firestore с помощью прослушивателя onSnapshot ().

Все работает нормально, но когда я перехожу на новую страницу (которая также имеет список, аналогичный списку на предыдущей странице, но с другими данными), данные из предыдущего списка по-прежнему отображаются на новой странице. Только когда я нажимаю на страницу где-то, новые данные отображаются.

Пример:

/home показывает список моих сообщений.

/friends показывает список моих друзей.

Когда я нажимаю /friends из /home, я все еще вижу список своих сообщений.

Я пытался размонтировать слушателя следующим образом:

  useEffect(() => {

      const posts = firebase
        .firestore()
        .collection('posts')
        .onSnapshot(function(querySnapshot) {

          var postsArray = [];

          querySnapshot.forEach(doc => {
              postsArray.push(doc.data());
          });

      setServiceProviderArray(postsArray);

      return function cleanup() {
          posts()
    };

  }, []);

Но это не сработает.

Я использую React-Router-Dom для маршрутизации.

Есть что-то, что я здесь упускаю. Большое спасибо.

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Этот бит немного сбивает с толку:

 return function cleanup() {
          posts()
    };

Что вы ожидаете от cleanup()?

В этом случае бит return () => posts(); откажется от прослушивателя в реальном времени, когда компонент размонтируется. Это просто означает, что если база данных Firestore изменится, когда компонент будет размонтирован, вы не получите обновления с новыми данными. Это хорошо, не меняй то, что ты здесь делаешь. Если вы не отмените подписку, вы все равно получите обновление, даже если компонент отсутствует на странице, и у вас будет утечка памяти. Подробнее об отключении слушателей здесь https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener

Звучит так, как будто вы хотите очистить данные при размонтировании. Для этого вам нужно написать функцию, которая очищает его. Функциональная противоположность setServiceProviderArray. Так что то, что очищает массив поставщика услуг. Затем вы хотите позвонить тогда, когда вы размонтировать. Может быть, setServiceProviderArray ([]); Итак ...

return () => {
  posts()
  clearServiceproviderArray()
};

Может быть setServiceProviderArray([]) сработает. Если это не поможет, поделитесь кодом для setServiceProviderArray(), и мы можем помочь вам создать clearServiceproviderArray(), написав его функциональную противоположность.

0 голосов
/ 22 января 2020

Было бы неплохо получить пример Sandbox или что-то еще, чтобы увидеть, как выглядит реализация, которую вы сделали. Поскольку есть много способов сделать это.

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

const [query, setQuery] = React.useState("posts");


  useEffect(() => {

      const posts = firebase
        .firestore()
        .collection(query)
        .onSnapshot(function(querySnapshot) {

          var postsArray = [];

          querySnapshot.forEach(doc => {
              postsArray.push(doc.data());
          });

      setServiceProviderArray(postsArray);

      return posts.unsubscribe();
    };

  }, [query]);

Таким образом, каждый раз, когда вы используете setQuery (), ваш postsArray будет заполняться заново.

надеюсь, это поможет

...