反应:与自定义钩子无限循环问题相关联的useContext

问题描述

我正在创建与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 };
};

此外,我正在控制台中登录钩子,并在上下文中检查它被调用了多少次,这是一种好习惯还是有一种更好的方法来检查组件安装的次数?

预先感谢

解决方法

您的代码陷入了循环,因为useEffect挂钩包含projects作为依赖项。随着useeffect中的代码更新projects,您的代码陷入无休止的状态更新和重新渲染周期。

查看您的代码,看来useEffectprojects语句中使用了if

if (JSON.stringify(allProjects) !== JSON.stringify(projects)) {
   setProjects(allProjects);
}

这似乎是您首先不应该做的事情。

如果您始终想接收实时更新,则可以observe projects集合,否则useEffect挂钩只能运行一次。

useEffect使用setProjects()函数,但是保证它不会改变,因此从useEffect钩子的依赖项数组中添加或省略它不会有什么区别。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...