提问者:小点点

阿波罗挂钩超过最大更新深度


以下代码在单击切换按钮后抛出错误“超过最大更新深度”。

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

演示

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>
        ))}
    </>
  );
};

共1个答案

匿名用户

为提高能见度:

在每个渲染中,allJobs变量都会重新分配给映射的节点或未定义的节点。由于它也是效果的一个依赖项,并且效果本身将导致重新渲染(如果visible为true),这将强制效果递归激发。

您可以回忆录allJobs,以防止在每次渲染中重新创建它。

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

演示