Как получить данные с помощью двух запросов к хранилищу данных в React Native - PullRequest
0 голосов
/ 03 августа 2020

В моей базе данных firestore я сослался на коллекцию Zutaten внутри коллекции Meal. Теперь я пытаюсь отобразить данные из коллекции Zutaten внутри моего компонента списка. Оператор console.log('ingredient data: ', documentSnapshot.data()) внутри моего второго снимка работает правильно и отображает данные из коллекции Zutaten. Но я не могу получить доступ к данным вне функции useEffect, поэтому я думаю, что ошибся с обработчиками реакции. Мой код:

function Meal() {
  const [loading, setLoading] = useState(true);
  const [meal, setMeal] = useState([]); // Initial empty array of meal
  const [ingredient, setIngredient] =  useState([]);
  
  useEffect(() => {
    const subscriber = firestore()
      .collection('Meal')
      .onSnapshot((querySnapshot) => {
        const meal = [];
        querySnapshot.forEach(documentSnapshot => {
          meal.push({
            ...documentSnapshot.data(),
            //key: documentSnapshot.id,
        });
          const ingredient = [];
          for (let i=0; i<documentSnapshot.data().Zutaten.length; i++) {
            documentSnapshot.data().Zutaten[i].get().then(documentSnapshot => {
              if (documentSnapshot.exists) {
                console.log('ingredient data: ', documentSnapshot.data())
                ingredient.push({
                  ...documentSnapshot.data(),
                  //key: documentSnapshot.data().id,
                });
              };
            })
            setIngredient(ingredient);
          }
      });
      setMeal(meal);
      setLoading(false);
    });

    // Unsubscribe from events when no longer in use
    return () => subscriber();
  }, []);

  console.log('this is it: ', ingredient);
  

  if (loading) {
    return <ActivityIndicator />;
  }

  return (
    <List
      style={styles.container}
      contentContainerStyle={styles.contentContainer}
      data={meal}
      renderItem={({ item }) => (
        <Card style={styles.item}>
          <Text style={styles.title}> {item.Name}  </Text>
          <Layout>
            <Image
              style={{ height: 128, borderRadius: 5, borderWidth: 2, borderColor: 'black', marginHorizontal: -20 }}
              source={{ uri: item.srcImage}}
            />
          </Layout>
        </Card>
      )}
    />
  );
}

1 Ответ

0 голосов
/ 03 августа 2020

Это действительно работает, как ожидалось. Поскольку все данные загружаются из Firestore асинхронно, они доступны только в обратном вызове. Таким образом, ваши вызовы setMeal и setLoading должны выполняться внутри этого обратного вызова.

Самый простой способ сделать это - вызвать setMeal внутри l oop следующим образом:

  useEffect(() => {
    const subscriber = firestore()
      .collection('Meal')
      .onSnapshot((querySnapshot) => {
        const meal = [];
        querySnapshot.forEach(documentSnapshot => {
          meal.push({
            ...documentSnapshot.data(),
            //key: documentSnapshot.id,
          });
          setMeal(meal); // this is moved
          const ingredient = [];
          for (let i=0; i<documentSnapshot.data().Zutaten.length; i++) {
            documentSnapshot.data().Zutaten[i].get().then(documentSnapshot => {
              if (documentSnapshot.exists) {
                console.log('ingredient data: ', documentSnapshot.data())
                ingredient.push({
                  ...documentSnapshot.data(),
                  //key: documentSnapshot.data().id,
                });
              };
            })
            setIngredient(ingredient);
          }
      });
      setLoading(false);
    });

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

Обновление : если вы также визуализируете ингредиенты (я не видел этого в коде, которым вы поделились), вам нужно будет установить его в состояние внутри обратного вызова, в которое вы загружаете ингредиенты. .

  useEffect(() => {
    const subscriber = firestore()
      .collection('Meal')
      .onSnapshot((querySnapshot) => {
        const meal = [];
        querySnapshot.forEach(documentSnapshot => {
          meal.push({
            ...documentSnapshot.data(),
            //key: documentSnapshot.id,
          });
          setMeal(meal); // this is moved
          const ingredient = [];
          for (let i=0; i<documentSnapshot.data().Zutaten.length; i++) {
            documentSnapshot.data().Zutaten[i].get().then(documentSnapshot => {
              if (documentSnapshot.exists) {
                console.log('ingredient data: ', documentSnapshot.data())
                ingredient.push({
                  ...documentSnapshot.data(),
                  //key: documentSnapshot.data().id,
                });
              };
              setIngredient(ingredient); // move this too
            })
          }
      });
      setLoading(false);
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...