繁体   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