apollo 钩子超出了最大更新深度
Maximum update depth exceeded with apollo hooks
以下代码在单击“切换”按钮后引发错误 "Maximum update depth exceeded"。
从依赖数组中删除 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>
))}
</>
);
};
为了更好的可见性:
每次渲染,您的 allJobs 变量都会重新分配给您的映射节点或未定义。由于它也是您的效果的依赖项,并且您的效果本身会导致重新渲染(如果 visible 为真),这会强制效果以递归方式触发。
您可以记忆 allJobs
以防止在每次渲染时重新创建它。
const allJobs = React.useMemo(() => {
return data ? data.allJobs.edges.map(edge => edge.node) : undefined;
}, [data]);
以下代码在单击“切换”按钮后引发错误 "Maximum update depth exceeded"。
从依赖数组中删除 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>
))}
</>
);
};
为了更好的可见性:
每次渲染,您的 allJobs 变量都会重新分配给您的映射节点或未定义。由于它也是您的效果的依赖项,并且您的效果本身会导致重新渲染(如果 visible 为真),这会强制效果以递归方式触发。
您可以记忆 allJobs
以防止在每次渲染时重新创建它。
const allJobs = React.useMemo(() => {
return data ? data.allJobs.edges.map(edge => edge.node) : undefined;
}, [data]);