简体   繁体   English

为什么自定义 hook ,带有 useEffect 的上下文会导致无限循环?

[英]why custom hook , context with useEffect lead to infinite loop?

why this simple code leads to infinite loop rendering Projects component and its child(naturally) and because of useEffect infinite loop accessing firebase ?为什么这个简单的代码会导致无限循环渲染 Projects 组件及其子组件(自然地)并且因为 useEffect无限循环访问firebase ? managing state with contextProvider which has imported useProjects custom hook.使用已导入 useProjects 自定义钩子的 contextProvider 管理状态。

custom hook :自定义钩子:

export const useProjects = () => {
  const [projects, setProjects] = useState([]);
  useEffect(() => {
    const db = firebase
      .firestore()
      .collection("projects")
      .where("userId", "==", "1234567890")
      .orderBy("projectId")
      .get();
    db.then((result) => {
      const allProjects = result.docs.map((project) => ({
        docId: project.id,
        ...project.data(),
      }));

      if (JSON.stringify(allProjects) !== JSON.stringify(projects)) {
        setProjects(allProjects);
      }
    }).catch((err) => {
      console.log("useProjects error", err);
    });
  }, [projects]);
  return { projects, setProjects };
};

Projects component:项目组成:

const Projects = () => {
  const [active, setActive] = useState(null);
  const { setSelectedProject } = useSelectedProjectValue();
  const { projects } = useProjectsValue();

  return (
    projects &&
    projects.map((project) => (
      <li
        key={Math.random()}
        className={
          active === project.projectId
            ? "sidebar__project active"
            : "sidebar__project"
        }
      >
        <div
          onClick={() => {
            setActive(project.projectId);
            setSelectedProject(project.projectId);
          }}
        >
          <IndividualProject
            className="individualProjectComp"
            project={project}
          />
        </div>
      </li>
    ))
  );
};

You are setting projects state within useEffect which takes projects as a dependency itself and even though you are comparing project value before setting, some change while stringifying the value is causing the state update each time.您在 useEffect 中设置项目状态,它将项目本身作为依赖项,即使您在设置之前比较项目值,字符串化值时的一些更改也会导致每次状态更新。

You can avoid it by not adding projects as a dependency to useEffect since projects is only being updated inside useEffect and not anywhere else您可以通过不将项目添加为useEffect的依赖项来避免它,因为projects仅在useEffect内部而不是其他任何地方更新

export const useProjects = () => {
  const [projects, setProjects] = useState([]);
  useEffect(() => {
    const db = firebase
      .firestore()
      .collection("projects")
      .where("userId", "==", "1234567890")
      .orderBy("projectId")
      .get();
    db.then((result) => {
      const allProjects = result.docs.map((project) => ({
        docId: project.id,
        ...project.data(),
      }));

      setProjects(allProjects);
    }).catch((err) => {
      console.log("useProjects error", err);
    });
  }, []);
  return { projects, setProjects };
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM