在我的firestore数据库中,我引用了Meal集合中的Zutaten集合。现在,我尝试在列表组件中显示来自Zutaten集合的数据。我的第二个快照中的console.log('ingredient data: ', documentSnapshot.data())
语句工作正常,并显示了Zutaten集合中的数据。但是我无法访问useEffect函数之外的数据,所以我认为我在使用react钩子时犯了一个错误。我的代码:
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>
)}
/>
);
}
这实际上是按预期工作的。由于所有数据都是从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);
});