阿波罗钩子超过了最大更新深度
Posted
技术标签:
【中文标题】阿波罗钩子超过了最大更新深度【英文标题】:Maximum update depth exceeded with apollo hooks 【发布时间】:2020-05-24 11:33:48 【问题描述】:以下代码在点击切换按钮后抛出错误“超出最大更新深度”。
从依赖数组中删除 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
变量都会重新分配给您的映射节点或undefined
。由于它也是您的效果的依赖项,并且您的效果本身会导致重新渲染(如果visible
为真),这会强制效果以递归方式触发。
您可以用useMemo
包裹allJobs
以防止在每次渲染时重新创建此数组。
***.com/questions/48497358/… - 这个答案可以帮助Maximum update depth exceeded
@bsekula 不适用于此处。可以将函数引用传递给 onClick 处理程序。
@tobiasfried 谢谢,它适用于useMemo
【参考方案1】:
为了更好的可见性:
每次渲染,您的 allJobs 变量都会重新分配给您的映射节点或未定义的节点。由于它也是您的效果的依赖项,并且您的效果本身会导致重新渲染(如果可见为真),这会强制效果以递归方式触发。
您可以记住 allJobs
以防止在每次渲染时重新创建它。
const allJobs = React.useMemo(() =>
return data ? data.allJobs.edges.map(edge => edge.node) : undefined;
, [data]);
Demo
【讨论】:
以上是关于阿波罗钩子超过了最大更新深度的主要内容,如果未能解决你的问题,请参考以下文章
@apollo/client 反应钩子 useQuery() 数据未定义