apollo 钩子超出了最大更新深度

Maximum update depth exceeded with apollo hooks

以下代码在单击“切换”按钮后引发错误 "Maximum update depth exceeded"。

从依赖数组中删除 allJobs 后它可以工作,但我想了解为什么会出现此错误以及如何更好地编写它。

Demo

import React from "react";
import { useQuery } from "@apollo/react-hooks";
import { gql } from "apollo-boost";

const JOBS = gql`
  query Jobs($cursor: String) {
    allJobs(first: 5, after: $cursor) {
      pageInfo {
        hasNextPage
        endCursor
      }
      edges {
        node {
          id
          jobTitle
        }
      }
    }
  }
`;

const Countries = () => {
  const [visible, setVisible] = React.useState(false);
  const [, setJobs] = React.useState([]);
  const { loading, data } = useQuery(JOBS, {
    fetchPolicy: "cache-and-network"
  });
  const allJobs = data ? data.allJobs.edges.map(edge => edge.node) : undefined;

  React.useEffect(() => {
    if (visible) {
      setJobs(allJobs);
    }
  }, [visible, allJobs]);

  const toggleVisible = () => {
    setVisible(!visible);
  };

  if (loading) return <p>Loading...</p>;

  return (
    <>
      <button onClick={toggleVisible}>Toggle</button>
      {visible &&
        allJobs.map(job => (
          <div key={job.id}>
            <p>{job.jobTitle}</p>
          </div>
        ))}
    </>
  );
};

为了更好的可见性:

每次渲染,您的 allJobs 变量都会重新分配给您的映射节点或未定义。由于它也是您的效果的依赖项,并且您的效果本身会导致重新渲染(如果 visible 为真),这会强制效果以递归方式触发。

您可以记忆 allJobs 以防止在每次渲染时重新创建它。

const allJobs = React.useMemo(() => {
  return data ? data.allJobs.edges.map(edge => edge.node) : undefined;
}, [data]);

Demo