[英]Firestore "get" function getting executed multiple times
我是 React-Native 和 Firebase 的新手,我正在将Firebase Cloud Firestore用于一个项目。 我正在尝试静态地从数据库中获取过滤的数据(因为我现在正在学习使用它),但不知何故我的函数被多次执行,读数的数量正在迅速增加,我有一些随机错误也。 我想知道出了什么问题。
这是我只处理数据库(Firestore.js)的文件的代码:
import React, { useState, useEffect } from "react";
import { ActivityIndicator } from "react-native";
import * as firebase from "firebase";
import "firebase/firestore";
function onResult(QuerySnapshot) {
console.log("Pegamos a coleção de Animais.");
}
function onError(error) {
console.error(error);
}
export function GetAnimalsByEspecie(especie) {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
console.log("entrou Especie");
const subscriber = firebase
.firestore()
.collection("Animal")
.where("especie", "==", especie)
.get()
.then((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
if (loading) {
console.log("loading");
return <ActivityIndicator />;
}
return animais;
}
export function GetAnimalsByNome(nomeAnimal) {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
console.log("entrou nome nooome");
const subscriber = firebase
.firestore()
.collection("Animal")
.where("nome", "==", nomeAnimal)
.get()
.then((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
if (loading) {
console.log("loading");
return <ActivityIndicator />;
}
return animais;
}
export default function GetAnimals() {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
useEffect(() => {
console.log("entrou listener");
const subscriber = firebase
.firestore()
.collection("Animal")
// .where('')
.onSnapshot((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
return () => subscriber();
}, []);
if (loading) {
console.log("loading");
return <ActivityIndicator />;
}
return animais;
}
这是我在屏幕上显示数据的文件的代码(index.js):
import React, { useState } from "react";
import {
View,
Text,
KeyboardAvoidingView,
StyleSheet,
Image,
TextInput,
TouchableHighlight,
ScrollView,
Button,
ActivityIndicator,
FlatList,
} from "react-native";
import { SearchBar } from "react-native-elements";
import { createStackNavigator } from "@react-navigation/stack";
import { SafeAreaView } from "react-native-safe-area-context";
import SubmitButton from "../../shared/SubmitButton";
import FocusAwareStatusBar from "../../shared/StatusBar";
import GetAnimals, {GetAnimalsByEspecie, GetAnimalsByNome} from "../../db/Firestore";
const styles = StyleSheet.create({
background: {
flex: 1,
backgroundColor: "#fafafa",
alignItems: "center",
justifyContent: "center",
},
regform: {
alignSelf: "stretch",
},
textInput: {
fontFamily: "Roboto_400Regular",
fontSize: 14,
alignSelf: "stretch",
paddingLeft: 12,
marginHorizontal: 16,
color: "#000000",
borderBottomColor: "#dcdcdc",
borderBottomWidth: 0.8,
paddingBottom: 8,
},
label: {
alignSelf: "stretch",
marginTop: 28,
marginBottom: 32,
paddingLeft: 28,
color: "#589b9b",
},
container: {
flex: 1,
justifyContent: "center",
alignSelf: "center",
height: 128,
width: 128,
backgroundColor: "#fff",
elevation: 4,
},
button: {
alignItems: "center",
backgroundColor: "#f1f2f2",
paddingTop: 44,
paddingBottom: 48,
},
infobox: {
backgroundColor: "#cfe9e5",
borderRadius: 4,
height: 80,
width: 328,
marginTop: 16,
marginHorizontal: 16,
justifyContent: "space-evenly",
alignContent: "center",
},
infotext: {
fontFamily: "Roboto_400Regular",
fontSize: 14,
color: "#434343",
paddingHorizontal: 15,
marginVertical: 11,
textAlign: "center",
},
});
export default function Animais() {
var animais = GetAnimalsByEspecie('shitzu');
const search = () => {
const [searchQuery, setSearchQuery] = useState("");
return (
<SearchBar
placeholder="Escreva aqui..."
onChangeText={""}
value={searchQuery}
/>)
};
return (
<SafeAreaView style={{ flex: 1 }}>
<FocusAwareStatusBar barStyle="light-content" backgroundColor="#88c9bf" />
<KeyboardAvoidingView style={styles.background}>
<View>
<Text>Animais</Text>
<FlatList
ListHeaderComponent={''}
data={animais}
renderItem={({ item }) => (
<View
style={{
height: 50,
width: 350,
flex: 1,
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Animal ID: {item.id}</Text>
<Text>Animal Name: {item.nome}</Text>
</View>
)}
/>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
我还没有使用 SearchBar,现在我只是想从数据库中获取和显示“especies”字段等于“shitzu”的数据。 有时我得到正确的信息,有时我得到错误。
谢谢您的帮助。
你应该把你的提取放在useEffect
里面,这样你就可以让它只运行一次。 否则,当您的 fetch 回调设置状态时,您将获得重新渲染,并且您的 fetch 代码将再次运行。 此外,它看起来像 GetAnimalsByEspecie,因为它调用钩子,它本身应该是一个钩子。 例如:
export function useAnimalsByEspecie(especie) {
const [loading, setLoading] = useState(true);
const [animais, setAnimais] = useState([]);
useEffect(() => {
const subscriber = firebase
.firestore()
.collection("Animal")
.where("especie", "==", especie)
.get()
.then((querySnapshot) => {
const animaisList = [];
querySnapshot.forEach((documentSnapshot) => {
animaisList.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setAnimais(animaisList);
setLoading(false);
});
}, [especie]);
return [animais, loading];
}
...这将被用作:
function Animais() {
var [animais, isLoading] = useAnimalsByEspecie('shitzu');
const search = () => {
const [searchQuery, setSearchQuery] = useState("");
return (
<SearchBar
placeholder="Escreva aqui..."
onChangeText={""}
value={searchQuery}
/>)
};
if (isLoading) {
return <ActivityIndicator />;
}
return (
<SafeAreaView style={{ flex: 1 }}>
<FocusAwareStatusBar barStyle="light-content" backgroundColor="#88c9bf" />
<KeyboardAvoidingView style={styles.background}>
<View>
<Text>Animais</Text>
<FlatList
ListHeaderComponent={''}
data={animais}
renderItem={({ item }) => (
<View
style={{
height: 50,
width: 350,
flex: 1,
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Animal ID: {item.id}</Text>
<Text>Animal Name: {item.nome}</Text>
</View>
)}
/>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.