Error: Maximum update depth exceeded (react state)

Error: Maximum update depth exceeded (react state)

我正在尝试在 React 函数组件中使用更新状态,但它不起作用。我尝试按照 pluralsite 上的教程进行操作,并将其应用到我自己的项目中。理想情况下,这段代码应该根据 ID 号查找产品,并将总数替换为新值。

不幸的是,我在设置状态时遇到错误。如果我将 useState(productNew) 切换为 useState(data[index]) 似乎不会出现错误。它们在结构上似乎相同,我不确定为什么会遇到这个问题。

这是我在 firefox 控制台 window 中收到的错误消息(该消息未显示在 Chrome 中)。在错误消息之上,屏幕显示为空白:

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops

同样,用新状态更新它时会发生这种情况,而尝试将其设置为原始状态值时不会发生错误。

对于如何解决这个问题有什么建议吗?

这是数据的样子。在这个例子中,我保存了数组的第一个元素。

export let data = [
    {
        name: "Name",
        description:
            "",
        products: [
            {
                id: 1,
                name: "Name 1",
                material: 1.05,
                time: 25,
                total: 0,
            },
            {
                id: 2,
                name: "Name 2",
                material: 3,
                time: 252,
                total: 0,
            },
        ],
    },
...
];
function CompareCard({}) {
    const index = 0;
    const [productData, setProductData] = useState(data[index]); 

function setTotalUpdate(id) {

        const productPrevious = productData.products.find(function (rec) {
            return rec.id === id;
        });

        const productUpdated = {
            ...productPrevious,
            total: 1,
        };
        const productNew = productData.products.map(function (rec) {
            return rec.id === id ? productUpdated : rec;
        });
        setProductData(productNew);
    }
setTotalUpdate(1)

return null;
}

您似乎是在函数组件的主体内调用 setState。这会导致您的组件在每次渲染时都设置状态,然后导致另一个渲染,另一个渲染……无限循环。

相反,您应该只在事件上或在 useEffect 挂钩内调用 setState。

此外,您的组件需要 return 一些 JSX,或者为 null。它不能 return 未定义。

function CompareCard({}) {
  const index = 0;
  const [productData, setProductData] = useState(data[index]);

  function setTotalUpdate(id) {
    const productPrevious = productData.products.find(function (rec) {
      return rec.id === id;
    });

    const productUpdated = {
      ...productPrevious,
      total: 1,
    };
    const productNew = productData.products.map(function (rec) {
      return rec.id === id ? productUpdated : rec;
    });
    setProductData(productNew);
  }
  
  useEffect(() => {
    // Only call setState within event handlers! 
    // Do not call setState inside the body of your function component
    setTotalUpdate(1);
  },[])

  // You need to return JSX or null
  return <p>productData: {JSON.stringify(productData)}</p>
}