我有一个NextJS应用程序,它使用Firebase实时数据库来获取数据。但是,我得到了一个InternalError:太多的递归每次我使用页面的生产版本。我在本地开发服务器上没有得到任何错误。
代码- index.js
import { ref, getDatabase, get, child, set } from "firebase/database";
import { useState, useEffect } from "react";
import { app } from "../lib/firebase";
import Subject from "../components/Subject";
export default function Student() {
const dbref = ref(getDatabase(app));
const timetable = {
Monday: ["DAA"],
Tuesday: ["COMP", "ALC"],
Wednesday: ["BEE", "OS"],
Thursday: ["OE", "IT", "DM"],
Friday: ["DBMS", "S&S"],
};
const days = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const [data, setData] = useState({});
const [date, setDate] = useState(
new Date().toLocaleDateString("en-GB").replaceAll("/", "-")
);
const [day, setDay] = useState(days[new Date().getDay()]);
useEffect(() => {
console.log("Data Fetched!");
get(child(dbref, "data/"))
.then((snapshot) => snapshot.val())
.then((d) => {
if (d) setData(d);
})
.catch((e) => console.error(e));
}, []);
useEffect(() => {
console.log("Data Updated!");
set(child(dbref, "data/"), data).catch((e) => console.error(e));
}, [data]);
return (
<main className="">
<h1 className="text-4xl">Student View : </h1>
<p>Selected Date : {date}</p>
<p>Day : {day}</p>
<p>Selected Day's subjects : {timetable[day].join(", ")}</p>
<h3>Set Date :</h3>
<input
type={"date"}
id="date"
name="date"
onChange={(e) => {
if (e.target.valueAsDate !== null) {
setDate(
e.target.valueAsDate
.toLocaleDateString("en-GB")
.replaceAll("/", "-")
);
setDay(days[e.target.valueAsDate.getDay()]);
}
}}
/>
{timetable[day].map((e) => (
<Subject key={e} name={e} data={data} setData={setData} date={date} />
))}
</main>
);
}
Subject.jsx
export default function name({ name, data, setData, date }) {
function todayTaken() {
setData((old) => ({
...old,
[date]: { ...old[date], [name]: 1 },
}));
}
function notTaken() {
setData((old) => ({
...old,
[date]: { ...old[date], [name]: 0 },
}));
}
function Cancelled() {
setData((old) => ({
...old,
[date]: { ...old[date], [name]: -1 },
}));
}
return (
<div className="border-2 p-4">
<h2>Subject : {name}</h2>
<div className="flex flex-row gap-4">
<button
className="bg-blue-500 py-2.5 px-4 text-white rounded-md"
onClick={todayTaken}
>
Class Taken Today
</button>
<button
className="bg-red-500 py-2.5 px-4 text-white rounded-md"
onClick={notTaken}
>
Not Taken Today
</button>
<button
className="bg-indigo-500 py-2.5 px-4 text-white rounded-md"
onClick={Cancelled}
>
Cancelled
</button>
<h2>
Today's status :{" "}
{data[date]===undefined || data[date][name] === undefined
? "Not set"
: data[date][name] === 1
? "Class Taken"
: data[date][name] === 0
? "Class Not Taken"
: data[date][name] === -1
? "Class Cancelled"
: ""}
</h2>
</div>
</div>
);
}
我不确定哪里出了问题,有人能告诉我哪里出了问题吗?第一个useEffect在组件挂载时从Firebase获取数据,然后当数据被更改时,数据被set在Firebase上,这意味着它不会触发重新渲染。我不确定这里出了什么问题。控制台没有提供任何有用的信息。
1条答案
按热度按时间roejwanj1#
您正在创建一个具有以下两种效果的无限循环:
1.第一个效果从数据库读取
/data
,并通过调用setData
将其设置为状态。1.第二个效果通过将
data
stats的值写入数据库来响应。1.这又会再次触发第一个效果,它会再次调用
setData
。1.然后再次触发第二个效果。
1.这种情况无休止地重复。
若要防止无限循环,请比较任一效果中的旧值和新值,如果它们相同,则跳过进一步处理。