React:useContext 与自定义挂钩无限循环问题关联
React: useContext associated with a custom hook infinite loop issue
我正在创建一个与 Google Firebase 配对的 todolist 应用程序来存储我的数据。在应用程序中,您可以创建项目来组织您的任务。我正在使用 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 };
};
此外,我正在控制台登录挂钩并在上下文中检查它被调用了多少次,这是好的做法还是有更好的方法来检查组件安装了多少次?
提前致谢
您的代码陷入循环,因为 useEffect
挂钩包含 projects
作为依赖项。当 useeffect
中的代码更新 projects
时,您的代码陷入状态更新和 re-render.
的无限循环中
查看您的代码,似乎 useEffect
在 if
语句中使用了 projects
if (JSON.stringify(allProjects) !== JSON.stringify(projects)) {
setProjects(allProjects);
}
这似乎是您一开始就不应该做的事情。
如果您总是想接收 real-time 更新,您可以 observe
projects
集合,否则 useEffect
挂钩应该只 运行 一次。
useEffect
使用 setProjects()
函数但保证不会更改,因此在 useEffect
挂钩的依赖数组中添加或省略它不会有什么不同。
我正在创建一个与 Google Firebase 配对的 todolist 应用程序来存储我的数据。在应用程序中,您可以创建项目来组织您的任务。我正在使用 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 };
};
此外,我正在控制台登录挂钩并在上下文中检查它被调用了多少次,这是好的做法还是有更好的方法来检查组件安装了多少次?
提前致谢
您的代码陷入循环,因为 useEffect
挂钩包含 projects
作为依赖项。当 useeffect
中的代码更新 projects
时,您的代码陷入状态更新和 re-render.
查看您的代码,似乎 useEffect
在 if
语句中使用了 projects
if (JSON.stringify(allProjects) !== JSON.stringify(projects)) {
setProjects(allProjects);
}
这似乎是您一开始就不应该做的事情。
如果您总是想接收 real-time 更新,您可以 observe
projects
集合,否则 useEffect
挂钩应该只 运行 一次。
useEffect
使用 setProjects()
函数但保证不会更改,因此在 useEffect
挂钩的依赖数组中添加或省略它不会有什么不同。