簡體   English   中英

Firestore“get”函數被多次執行

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM