【问题标题】:Why this setState caused infinite loop?为什么这个 setState 会导致无限循环?
【发布时间】:2021-10-06 13:19:56
【问题描述】:

我创建了一个带有渲染调用细节的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 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    问题在于你的回报:

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

    在这里,您正在调用函数onToggleArchived,大概(它不在您发布的代码中)进行状态更新。

    如何解决: 将其包装在箭头函数中

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

    【讨论】:

      【解决方案2】:

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

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

      原始答案

      在组件中我使用 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
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-17
        • 1970-01-01
        • 2012-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-06
        • 2011-07-31
        相关资源
        最近更新 更多