Firebase onSnapShot不断通话

时间:2020-09-12 18:01:53

标签: javascript reactjs firebase google-cloud-firestore

我是React JS的新手。使用Firebase处理ToDo应用程序。

import React, { useState, useEffect } from "react";
import "./App.css";
import ToDoInput from "./ToDoInput";
import db from "./firebase";
import ToDoItem from "./ToDoItem";

function App() {
  const [toDos, setToDos] = useState([{ id: 1, task: "asd", status: false }]);
  useEffect(() => {
    console.log("User effect");
    db.collection("ToDo")
      .orderBy("createdAt")
      .onSnapshot((snapshot) => {
        setToDos(
          snapshot.docs.map((doc) => ({
            id: doc.id,
            task: doc.data().task,
            createdAt: doc.data().createdAt,
            status: doc.data().status,
          }))
        );
      });
  });
  return (
    <div className="app">
      <ToDoInput />
      {toDos.map((toDo) => (
        <ToDoItem
          key={toDo.id}
          task={toDo.task}
          createdAt={toDo.createdAt}
          status={toDo.status}
        />
      ))}
    </div>
  );
}

export default App;

在上面的代码中,onSnapshot功能不断触发相同的数据,并且UI处于持续渲染状态。

关于如何解决这个问题的想法。

1 个答案:

答案 0 :(得分:1)

您需要在useEffect中传递一个空数组参数。这样,仅在组件上第一次调用该函数。您的代码将在组件上以及状态每次更改时运行。由于您正在useEffect内更改状态,因此您陷入了循环。

执行以下操作:

useEffect(() => {
    console.log("User effect");
    db.collection("ToDo")
      .orderBy("createdAt")
      .onSnapshot((snapshot) => {
        setToDos(
          snapshot.docs.map((doc) => ({
            id: doc.id,
            task: doc.data().task,
            createdAt: doc.data().createdAt,
            status: doc.data().status,
          }))
        );
      });
  }, []); 

详细了解here on the notes