我正在创建与Google Firebase配对的待办事项应用程序,以存储我的数据。在应用程序中,您可以创建项目来组织任务。我正在使用useContext使我的应用程序可跨应用程序的所有组件进行访问。我的上下文在挂载时使用自定义钩子调用firebase来获取登录用户的项目(如果用户未在firebase中存储任何项目,则为空数组)。
我的问题是我的contextProvider进入了挂载循环,对firebase进行了新调用,以在每次挂载时设置项目(即使项目没有更改)。上下文实际上在我的应用程序中正常工作,我只意识到它正在循环,因为我一天之内就达到了可在freeplan上对firebase进行的最大调用。
这是我的上下文代码:
import React, { createContext, useContext } from "react";
import PropTypes from "prop-types";
import { useProjects } from "../Hooks/index";
export const ProjectsContext = createContext();
export const ProjectsProvider = ({ children }) => {
const { projects, setProjects } = useProjects();
return (
<ProjectsContext.Provider value={{ projects, setProjects }}>
{children}
</ProjectsContext.Provider>
);
};
export const useProjectsValue = () => useContext(ProjectsContext);
这是我的自定义钩子useProjects()的代码,该代码调用firebase来检索项目:
export const useProjects = () => {
const [projects, setProjects] = useState([]);
useEffect(() => {
db.collection("projects")
.where("userId", "==", "uBnTwu5ZfuPa5BE0xlkL")
.orderBy("projectId")
.get()
.then((snapshot) => {
const allProjects = snapshot.docs.map((project) => ({
...project.data(),
docId: project.id,
}));
if (JSON.stringify(allProjects) !== JSON.stringify(projects)) {
setProjects(allProjects);
}
});
}, [projects]);
return { projects, setProjects };
};
此外,我正在控制台中登录钩子,并在上下文中检查它被调用了多少次,这是一种好习惯还是有一种更好的方法来检查组件安装的次数?
预先感谢
答案 0 :(得分:1)
您的代码陷入了循环,因为useEffect
挂钩包含projects
作为依赖项。随着useeffect
中的代码更新projects
,您的代码陷入无休止的状态更新和重新渲染周期。
查看您的代码,看来useEffect
在projects
语句中使用了if
if (JSON.stringify(allProjects) !== JSON.stringify(projects)) {
setProjects(allProjects);
}
这似乎是您首先不应该做的事情。
如果您始终想接收实时更新,则可以observe
projects
集合,否则useEffect
挂钩只能运行一次。
useEffect
使用setProjects()
函数,但是保证它不会改变,因此从useEffect
钩子的依赖项数组中添加或省略它不会有什么区别。