Использование useEffect () Hook и Async / Await для извлечения данных из Firebase / Firestore - PullRequest
2 голосов
/ 04 октября 2019

1. Мое намерение:

Использование useEffect () перехватывать для инициализации переменной состояния компонента из реквизита, данные которого извлекаются из firebase с использованием mapStateToProps () .


2. Проблема: невозможно инициализировать переменную состояния компонента

  • Идея состоит в том, что useEffect будет запускаться только один раз, когда компонент монтируется. В этом окне инициализации я хочу загрузить данные из firebase в локальную переменную состояния этого компонента.

  • Работает нормально, когда запускает пример из этого урока . В нем он извлекает данные с помощью axios () в функции async / await . Смотрите ниже раздел 3 для его кода.

  • Но когда я делал это, пытаясь извлечь данные из реквизита, который синхронизирован или инициализирован Firestore, я продолжал получать ноль, не в состоянии извлечь данные из возвращенного resultиз моей функции асинхронного / ожидания.

  • Я думаю, это потому, что мое непонимание асинхронного / ожидание. Мне не удалось создать действительную асинхронную / ожидающую функцию для извлечения данных из реквизита.

Вопрос:

Я подозреваю, что в этом проблема. Итак, как правильно написать функцию async / await , которая правильно извлекает данные из реквизита, синхронизированного с firebase?

Мой код проблемы:

    import React, { useState, useEffect} from "react";
    import { connect } from "react-redux";
    import { firestoreConnect } from "react-redux-firebase";
    import { compose } from "redux";

    const app = props => {
      const { order } = props;  
      const [data, setData] = useState({});

      useEffect(() => {
        const fetchData = async () => {
          const result = await (() => {
            return new Promise(resolve => {
              if (order) { resolve(order); }
            });
          })();
          setData(result);
        };
        fetchData();
      }, []);
      /** if I leave useEffect's second argument empty, which is intended to run only once at the beginning, then i'm getting null  */

    ...

    const mapStateToProps = state => {
      const id = "DKA77MC2w3g0ACEy630g"; // docId for testing purpose.
      const orders = state.firestore.data.orders;
      const order = orders ? orders[id] : null;        
      return {
        order: order
      };
    };

    export default compose(
      connect(mapStateToProps),
      firestoreConnect([{collection: "orders"}])
    )(app);

Что я пробовал:

  • Если я добавлю заказ во второй аргумент, тогда он будет правильно загружать данные в переменную состояния компонента. Но он перезагрузит данные реквизита в переменную состояния компонента и удалит все изменения в каждом цикле повторного рендеринга.
 useEffect(() => {
        ...
      }, [order]);
  • Is mapStateToProps () происходит после первоначального монтирования компонента? Потому что это объяснит, почему в начальном эффекте реквизит всегда пуст.

3. Учебное пособие У меня было следующее: выборка данных с помощью хуков

Мне удалось успешно извлечь данные с использованием методов из этого урока :

  const [data, setData] = useState({ hits: [] });
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        "https://hn.algolia.com/api/v1/search?query=redux"
      );
      setData(result.data);
    };
    fetchData();
  }, []);
...