[英]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.