繁体   English   中英

如何从 firebase firestore 获取数据并将数据存储在 useState 钩子中

[英]How to fetch data from firebase firestore and store the data in useState hook

我正在从 firebase 获取所有docs ,我成功地做到了,我什至可以在控制台中记录它。

通过列表映射是问题所在。

fetch API 在返回数据之前需要一些时间,而我的 map 函数在调用组件后立即运行,此时 API 没有返回任何内容,因此 map 函数将没有任何映射。

import { firebaseDB } from "./db";
import { collection, getDocs } from "firebase/firestore";

const responseArr: any[] = [];

// GETS ALL AVAILABLE DOCS IN GOALs COLLECTION
const getAllGoals = async () => {
  const response = await getDocs(collection(firebaseDB, "goals"));
  response.forEach((doc) => {
    responseArr.push(doc.data());
  });
};

export { getAllGoals, responseArr };

现在我只想等待响应,然后将其存储在useState()数组中。

import React, { useEffect, useState } from "react";
import OnprogressGoals from "./OnprogressGoals";
import GoalsDone from "./GoalsDone";
import { getAllGoals, responseArr } from "../../containers/GetAllGoals";

const GoalList = (props: any) => {
  const [refresh, setrefresh] = useState([]);
  useEffect(() => {
    getAllGoals();
    responseArr.map((goal) => {
      const goaler: any = [...refresh, goal];
      setrefresh(goaler);
    });
  }, []);

  console.log(refresh);

  const OnprogressGoalsResponse = responseArr.filter(
    (Goal) => Goal.GoalCompletion === "Onprogress"
  );

  const GoalsDoneResponse = responseArr.filter(
    (Goal) => Goal.GoalCompletion === "Done"
  );
  return (
    <div className="h-[85%] overflow-y-scroll scrollbar-thin scrollbar-thumb-gray-900 scrollbar-track-gray-50">
      <button onClick={() => alert("I am clicked")}>click me</button>
      <table className="w-full h-full">
        <>
          <tr className="border-b px-5">
            <td className="text-sm font-medium py-5 pl-5">
              <span>Date created</span>
            </td>
            <td className="text-sm font-medium py-5">
              <span className="border-l pl-3">Goal name</span>
            </td>
            <td className="text-sm font-medium py-5">
              <span className="border-l pl-3">Due date</span>
            </td>
            <td className="text-sm font-medium py-5 pr-5">
              <span className="border-l pl-3">Goal target</span>
            </td>
          </tr>
          <tr>
            <td colSpan={4} className="px-5">
              <h1 className="py-5 font-semibold text-2xl">On progress</h1>
            </td>
          </tr>
          {/* {console.log(`Goal List - ${props.goalsList}`)} */}
          <OnprogressGoals
            ShowGoalDetail={props.ShowGoalDetail}
            goalsList={OnprogressGoalsResponse}
          />
          <tr>
            <td colSpan={4} className="px-5">
              <h1 className="py-5 font-semibold text-2xl">Goal done</h1>
            </td>
          </tr>
          <GoalsDone
            ShowGoalDetail={props.ShowGoalDetail}
            goalsList={GoalsDoneResponse}
          />
        </>
      </table>
    </div>
  );
};

export default GoalList;

您的依赖项数组为空,这就是为什么 useEffect 在渲染后仅调用一次,并且您的组件无法在 responeArr 中渲染更新数据。 因此,要在加载数据时调用它,请将您的responseArr作为依赖项放在 useEffect 中。 只需使用以下代码更新您的 useEffect

useEffect(() => {
    getAllGoals();
    responseArr&&responseArr.map((goal) => {
      const goaler: any = [...refresh, goal];
      setrefresh(goaler);
    });
  }, [responseArr]);

这是正确的,因为responseArr不等待 getAllGoals。 试试这个:

    useEffect(() => {
        getDocs(collection(firebaseDB, "goals")).then((response) => {
            response.forEach((goal) => {
            const goaler: any = [...refresh, goal];
            setrefresh(goaler);
            }
        }
        );
      }, []);

删除 responseArr 并将 responseArr 用作 useState(),希望对您有所帮助

// const responseArr = []; it not update your component after rendeing component

let ArrEmpWithType : Array<any> = []
const GoalList = (props: any) => {
    const [responseArr, setresponseArr] = useState(ArrEmpWithType);
    const [refresh, setrefresh] = useState([]);
    const getAllGoals = async () => {
        const response = await getDocs(collection(firebaseDB, "goals"));
        response.forEach((doc) => {
            let Mydoc: any = doc.Data();
            Mydoc.id = doc.id;
            setresponseArr([...responseArr, Mydoc]) 
        });

        
    };
   
    useEffect(() => {getAllGoals(); }, []);
    useEffect(() => { }, [responseArr]);// it help rerender after update responseArr 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM