我正在使用 .onSnapshot 从 Fire 商店实时获取数据,而且效果很好,我按预期接收数据。问题是我接收了多组数据,组件没有等到所有数据都接收到才渲染。
所以我的问题是,使用我当前的代码,它们是否可以让我在显示所有数据集之前等待获取它们?
我当前的代码是:
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;
答案 0 :(得分:2)
使用状态 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>}
</>
);
}
答案 1 :(得分:1)
所以我设法以某种方式修复它。感谢朱利安的帮助
我所做的是创建一个承诺数组,只要数据发生变化就会执行。代码是:
#include <iostream>
int main()
{
constexpr size_t array_size{1000000000};
int stack[array_size];
stack[0] = 0;
for(size_t i{1}; i<array_size; i++)
stack[i] = stack[i-1] + 1;
std::cout << sizeof(stack) << "\n";
std::cout << "Last element: " << stack[array_size - 1] << "\n";
return 0;
}