为什么这个setState会导致无限循环?



我创建了一个具有渲染调用详细信息的react组件,在组件中我使用useEffect来设置callInfo状态,然后它引起了无限循环,即使我使用[]作为第二个参数,谁能帮助我解决这个问题,谢谢!

import { useLocation } from "react-router-dom";
import { useState, useEffect } from "react";
const ActivityDetail = ({ onToggleArchived }) => {
const { call } = useLocation().state;
const [callInfo, setCallInfo] = useState(null);
console.log({...call});
useEffect(() => {
setCallInfo({ ...call });
}, [])
return (
<div>
<h3 className="title">Call Details</h3>
<hr />
{
callInfo && <div>
<p>From: {callInfo.from}</p>
<p>To: {callInfo.to}</p>
<p>Time: {callInfo.created_at}</p>
<button onClick={onToggleArchived(callInfo.id)}>
{callInfo.is_archived ? "Unarchive" : "Archive"}
</button>
</div>
}
</div>
)
}
export default ActivityDetail

这是错误信息:错误:超出了最大更新深度。当组件在componentWillUpdate或componentdiduupdate中重复调用setState时,就会发生这种情况。React限制嵌套更新的数量以防止无限循环。

问题出在你的回报上:

<button onClick={onToggleArchived(callInfo.id)}>
{callInfo.is_archived ? "Unarchive" : "Archive"}
</button>

在这里,你正在调用函数onToggleArchived,它可能(它不在你发布的代码中)做状态更新。

如何修复:用箭头函数

封装
<button onClick={()=>onToggleArchived(callInfo.id)}>
{callInfo.is_archived ? "Unarchive" : "Archive"}
</button>

编辑:除了关于滥用状态的原始答案(您需要纠正)之外,我还错过了您调用函数而不是包装它的要点:

<button onClick={() => onToggleArchived(callInfo.id)}>
// instead of 
<button onClick={onToggleArchived(callInfo.id)}>

原始答案

在组件I使用useEffect设置callInfo状态

但这是一个问题,因为call不是组分状态-它来自useLocation()。让它从那里来,把组件状态的东西都去掉。

。把它当作道具。

import { useLocation } from "react-router-dom";
import { useState, useEffect } from "react";
const ActivityDetail = ({ onToggleArchived }) => {
const { call: callInfo } = useLocation().state;
return (
<div>
<h3 className="title">Call Details</h3>
<hr />
{
callInfo && <div>
<p>From: {callInfo.from}</p>
<p>To: {callInfo.to}</p>
<p>Time: {callInfo.created_at}</p>
<button onClick={() => onToggleArchived(callInfo.id)}>
{callInfo.is_archived ? "Unarchive" : "Archive"}
</button>
</div>
}
</div>
)
}
export default ActivityDetail

最新更新