如何在 React Native 中使用两个 firestore 查询获取数据
How to get data using two firestore queries in react native
在我的 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>
)}
/>
);
}
这实际上按预期工作。由于所有数据都是从 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);
});
在我的 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>
)}
/>
);
}
这实际上按预期工作。由于所有数据都是从 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);
});