0

在我的 firestore 数据库中,我引用了 Meal 集合中的 Zutaten 集合。现在我尝试在我的列表组件中显示来自 Zutaten 集合的数据。我的第二个快照中的console.log('ingredient data: ', documentSnapshot.data())语句正常工作,并显示了 Zutaten 集合中的数据。但是我无法访问 useEffect 函数之外的数据,所以我认为我在 react-hooks 上犯了一个错误。我的代码:

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>
      )}
    />
  );
}

4

1 回答 1

0

这实际上按预期工作。由于所有数据都是从 Firestore 异步加载的,因此仅在回调中可用。因此,您对setMeal并且setLoading将需要在该回调中进行调用。

setMeal最简单的方法是像这样在循环内调用:

  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);
    });
于 2020-08-03T17:45:02.113 回答