当我尝试使用 useEffect 从 firebase 获取信息到 nextjs 时出现无限循环
Infinity loop when I try to get information from firebase into nextjs using useEffect
我正在使用 NextJS 为项目创建视频部分。我在 firebase 存储.
中有这些视频
我创建了一个动态路由,它从存储桶的特定引用启动所有视频。例如,我的存储桶是 somebucket 并且有一个名为 training 的文件夹,其中包含类别(category-1、category-2、category-3)。每个类别将是一个动态路由,例如 localhost:3000/training/category-1。到这里,一切都很好。
动态路由文件[id].js
// ReactJS
import { useState, useEffect } from "react";
// NextJS
import { useRouter } from "next/router";
// Hooks
import { withProtected } from "../../../hook/route";
// Components
import DashboardLayout from "../../../layouts/Dashboard";
// Firebase
import { getMetadata, listAll, ref } from "firebase/storage";
import { storage } from "../../../config/firebase";
// Utils
import capitalize from "../../../utils/capitalize";
import { PlayIcon } from "@heroicons/react/outline";
function Video() {
// States
const [videos, setVideos] = useState([]);
// Routing
const router = useRouter();
const { id } = router.query;
// Reference
const reference = ref(storage, `training/${id}`);
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos);
});
}
exec();
}, [reference, videos]);
return (
<DashboardLayout>
<h2>{capitalize(reference.name)}</h2>
<section>
<video controls controlsList="nodownload">
<source
src="https://example.com"
type="video/mp4"
/>
</video>
<ul role="list" className="divide-y divide-gray-200 my-4">
{videos.map((video) => (
<li key={video.name} className="py-4 flex">
<div className="ml-3 flex flex-row justify-start items-center space-x-3">
<PlayIcon className="w-6 h-6 text-gray-600" />
<p className="text-sm font-medium text-gray-900">
{video.name}
</p>
</div>
</li>
))}
</ul>
</section>
</DashboardLayout>
);
}
export default withProtected(Video);
我根据路线进行动态参考:
// Reference
const reference = ref(storage, `training/${id}`);
如前所述,此引用将使用 listAll 方法列出:
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos);
});
}
exec();
}, [reference]);
我将元素作为数组推送到状态,然后状态将由组件迭代。显然工作罚款,但我有一个无限循环:
有人知道为什么会这样吗?
我不确定问题出在哪里,但在 useEffects 数组依赖项列表中只包含 id 参数不是更好吗。
我认为这会更好,因为您只有不同的视频,具体取决于路线,所以只有当路线改变时,useEffect 才必须重新运行。
你的问题可能出在这个
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos); //update `videos` again --> call `useEffect` again due to `videos` update
});
}
exec();
}, [reference, videos]); //`videos` dependency
您应该在 useEffect
依赖项列表中删除 videos
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos);
});
}
exec();
}, [reference]);
我正在使用 NextJS 为项目创建视频部分。我在 firebase 存储.
中有这些视频我创建了一个动态路由,它从存储桶的特定引用启动所有视频。例如,我的存储桶是 somebucket 并且有一个名为 training 的文件夹,其中包含类别(category-1、category-2、category-3)。每个类别将是一个动态路由,例如 localhost:3000/training/category-1。到这里,一切都很好。
动态路由文件[id].js
// ReactJS
import { useState, useEffect } from "react";
// NextJS
import { useRouter } from "next/router";
// Hooks
import { withProtected } from "../../../hook/route";
// Components
import DashboardLayout from "../../../layouts/Dashboard";
// Firebase
import { getMetadata, listAll, ref } from "firebase/storage";
import { storage } from "../../../config/firebase";
// Utils
import capitalize from "../../../utils/capitalize";
import { PlayIcon } from "@heroicons/react/outline";
function Video() {
// States
const [videos, setVideos] = useState([]);
// Routing
const router = useRouter();
const { id } = router.query;
// Reference
const reference = ref(storage, `training/${id}`);
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos);
});
}
exec();
}, [reference, videos]);
return (
<DashboardLayout>
<h2>{capitalize(reference.name)}</h2>
<section>
<video controls controlsList="nodownload">
<source
src="https://example.com"
type="video/mp4"
/>
</video>
<ul role="list" className="divide-y divide-gray-200 my-4">
{videos.map((video) => (
<li key={video.name} className="py-4 flex">
<div className="ml-3 flex flex-row justify-start items-center space-x-3">
<PlayIcon className="w-6 h-6 text-gray-600" />
<p className="text-sm font-medium text-gray-900">
{video.name}
</p>
</div>
</li>
))}
</ul>
</section>
</DashboardLayout>
);
}
export default withProtected(Video);
我根据路线进行动态参考:
// Reference
const reference = ref(storage, `training/${id}`);
如前所述,此引用将使用 listAll 方法列出:
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos);
});
}
exec();
}, [reference]);
我将元素作为数组推送到状态,然后状态将由组件迭代。显然工作罚款,但我有一个无限循环:
有人知道为什么会这样吗?
我不确定问题出在哪里,但在 useEffects 数组依赖项列表中只包含 id 参数不是更好吗。
我认为这会更好,因为您只有不同的视频,具体取决于路线,所以只有当路线改变时,useEffect 才必须重新运行。
你的问题可能出在这个
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos); //update `videos` again --> call `useEffect` again due to `videos` update
});
}
exec();
}, [reference, videos]); //`videos` dependency
您应该在 useEffect
依赖项列表中删除 videos
useEffect(() => {
function exec() {
listAll(reference).then((snapshot) => {
const videos = [];
snapshot.items.forEach((video) => {
videos.push(video);
});
setVideos(videos);
});
}
exec();
}, [reference]);