簡體   English   中英

為什么這個setState導致死循環?

[英]Why this setState caused infinite loop?

我創建了一個帶有渲染調用細節的反應組件,在組件中我使用 useEffect 設置 callInfo state,然后它導致無限循環,即使我使用 [] 作為第二個參數,誰能幫我解決這個問題,謝謝!

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

這是錯誤信息:Error: Maximum update depth exceeded。 當組件在 componentWillUpdate 或 componentDidUpdate 中重復調用 setState 時,就會發生這種情況。 React 限制嵌套更新的數量以防止無限循環。

問題在於您的回報:

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

在這里,您正在調用 function onToggleArchived ,它大概(它不在您發布的代碼中)執行 state 更新。

如何修復:用箭頭包裹它 function

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

編輯:除了關於濫用 state 的原始答案(您需要更正)之外,我還漏掉了您調用 function 而不是包裝它的要點:

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

原始答案

在組件中我使用 useEffect 來設置 callInfo state

但這是一個問題,因為call不是組件 state - 它來自useLocation() 就讓它從那里來,並完全刪除組件 state 的東西。

即把它當作道具。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM