在进行之前如何等待Firebase数据被获取?



我正在用. onsnapshot实时从Fire store获取数据,它工作得很好,我按预期接收数据。问题是我正在接收多组数据,而组件在呈现之前不会等到接收到所有数据。

所以我的问题是,与我目前的代码,是他们的一种方式,我可以等待所有集我的数据被获取之前显示它们?

我当前的代码是:

import React, {useEffect, useState} from 'react';
import {ActivityIndicator, Dimensions, Text, View} from 'react-native';
import firestore from '@react-native-firebase/firestore';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import FolloweringScreens from './FolloweringScreens';
import {TouchableOpacity} from 'react-native-gesture-handler';
const {width, height} = Dimensions.get('screen');
function Following({urlname, navigation}) {
const [followingData, setfollowingData] = useState([]);
// Follower counts, displayname, image
const fetchData = () => {
const dataRef = firestore().collection('usernames');
dataRef
.doc(urlname)
.collection('Following')
.onSnapshot((snapshot) => {
snapshot.forEach((doc) => {
dataRef.doc(doc.id.toLowerCase()).onSnapshot((followerDoc) => {
const data = followerDoc.data();
setfollowingData((prev) => [
...prev,
{
profileName: doc.id,
displayName: data.userName,
followerCount:
data.followers !== undefined ? data.followers : 0,
followingCount:
data.following !== undefined ? data.following : 0,
image: data.imageUrl ? data.imageUrl : null,
},
]);
});
});
});
};
useEffect(() => {
fetchData();
}, []);
return (
<>
<View
style={{
left: width * 0.04,
top: 50,
flexDirection: 'row',
alignItems: 'center',
width: '80%',
height: '4%',
marginBottom: 5,
}}>
{/* {console.log('followin', followingData)} */}
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Icon name="menu" color="#222" size={30} />
</TouchableOpacity>
<Text style={{left: width * 0.05}}>Following</Text>
</View>
{followingData === [] ? (
<ActivityIndicator size="large" color="black" />
) : (
<>
<FolloweringScreens data={followingData} />
</>
)}
</>
);
}
export default Following;

使用状态isLoading默认为true,然后在快照解析时将isLoading设置为false,并在isLoading为true时显示加载指示器,在isLoading为false时显示ui。然后你将更新推送到你的状态,用户将在完全加载后看到数据。

也会使用类似的东西。很奇怪的一件事是,您将每个快照更改推入一个数组,换句话说,随着时间的推移,这个数组保存了同一对象的更改历史。故意的吗?

function Following({ urlname }) {
const [followingData, setfollowingData] = useState([]);
const [isLoading, setIsLoading] = useState(true);
// Follower counts, displayname, image
const onSnapshot = useCallback((snapshot) => {
snapshot.forEach((doc) => {
dataRef.doc(doc.id.toLowerCase()).onSnapshot((followerDoc) => {
const data = followerDoc.data();
// push new document data into an array
setfollowingData((prev) => [
...prev,
{
profileName: doc.id,
displayName: data.userName,
followerCount: data.followers !== undefined ? data.followers : 0,
followingCount: data.following !== undefined ? data.following : 0,
image: data.imageUrl ? data.imageUrl : null
}
]);
// or set the new data to state, by just setting the document data
setfollowingData(data);
setIsLoading(false);
});
});
}, []);
useEffect(() => {
const dataRef = firestore().collection("usernames");
const cleanup = dataRef
.doc(urlname)
.collection("Following")
.onSnapshot(onSnapshot);
return cleanup;
}, [onSnapshot, urlname]);
return (
<>
{isLoading && <p>Loading</p>}
{!isLoading && <p>Show data {followingData.length}</p>}
</>
);
}

所以我设法解决了它。感谢Julian的帮助

我所做的是创建一个承诺数组,它将在数据更改时执行。代码是:

import React, {useCallback, useEffect, useState} from 'react';
import {ActivityIndicator, Dimensions, Text, View} from 'react-native';
import firestore from '@react-native-firebase/firestore';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import FolloweringScreens from './FolloweringScreens';
import {TouchableOpacity} from 'react-native-gesture-handler';
const {width, height} = Dimensions.get('screen');
function Following({urlname, navigation}) {
const [followingData, setfollowingData] = useState();
const [loading, setLoading] = useState(true);
// Following counts, displayname, image
const fetchData = useCallback(() => {
const dataRef = firestore().collection('usernames');
dataRef
.doc(urlname)
.collection('Following')
.limit(25)
.onSnapshot((snapshot) => {
let promises = [];
snapshot.forEach((doc) => {
const promise = dataRef
.doc(doc.id.toLowerCase())
.get()
.then((followerDoc) => {
const data = followerDoc.data();
return {
profileName: doc.id,
displayName: data.displayName
? data.displayName
: data.userName,
followerCount:
data.followers !== undefined ? data.followers : 0,
followingCount:
data.following !== undefined ? data.following : 0,
image: data.imageUrl ? data.imageUrl : null,
};
});
promises.push(promise);
});
Promise.all(promises)
.then((res) => setfollowingData(res))
.then(setLoading(false));
});
}, []);
useEffect(() => {
const dataRef = firestore().collection('usernames');
const cleanup = dataRef
.doc(urlname)
.collection('Following')
.limit(25)
.onSnapshot(fetchData);
return cleanup;
// fetchData();
}, [urlname, fetchData]);
return (
<>
<View
style={styles}>
<TouchableOpacity onPress={() => navigation.openDrawer()}>
<Icon name="menu" color="#222" size={30} />
</TouchableOpacity>
<Text style={{left: width * 0.05}}>Following</Text>
</View>
{loading ? (
<ActivityIndicator size="large" color="black" />
) : (
<>
<FolloweringScreens data={followingData} />
</>
)}
</>
);
}
export default Following;

最新更新