如何避免此消息警告"Maximum update depth exceeded..."在NextJs上



on NextJs我不明白,如何使用效果的工作。我需要做什么,以停止收到这个警告信息最大更新深度:

下面的代码是调用ListContainer组件的页面,该页向容器中添加了一个项。

页面JSX:

import { useState } from "react";
import AppLayout from "../components/AppLayout";
import ListContainer from "../components/ListContainer";
export default function componentCreator(){


const [item,setItem] = useState([])   
/* add item to container */
function addItem(){
let newItem = item
newItem.push({
produto: 'Skol 350ml',
preco: '1200,00',
quantidade: 'cx c/ 15 unidades'
})
setItem(newItem)
}
return (
<AppLayout>
<ListContainer items={item} setItems={setItem}/>
<div className="productcardbuttonshow" onClick={() => addItem()}>ADICIONAR</div>
</AppLayout>
)
}

下面的组件处理项目,删除或添加。但它的工作,但在控制台触发有关更新的警告消息。组件ListContainer.jsx:

import { useState,useEffect } from "react";
export default function ListContainer(props){
const [html,setHTML] = useState(null)
const [item,setItem] = useState(props.items)

/* refresh html container */
useEffect(() => {
const itemHTML = item.map((itemmap,id) => {
return (
<div id={id} onClick={() => delItem(id)} className="itemProposta">
{itemmap.produto} - {itemmap.quantidade} - R$ {itemmap.preco}
</div>
)
})
setHTML(itemHTML)
})
/* remove item from container */
function delItem(id){
let itemlist = props.items
itemlist.splice(id,1)
props.setItems(itemlist)
}
return (
<>
{html}
</>
)
}

你正在进入一个无限循环的渲染。这段代码负责:

useEffect(() => {
const itemHTML = item.map((itemmap,id) => {
return (
<div id={id} onClick={() => delItem(id)} className="itemProposta">
{itemmap.produto} - {itemmap.quantidade} - R$ {itemmap.preco}
</div>
)
})
setHTML(itemHTML)
})

useEffect中的这个回调将在每次渲染后运行,因为没有依赖数组。这意味着在每次渲染之后,setHTML(itemHTML)被调用。即使数组itemHTML的组成对象相同,也会创建一个新的数组引用。因为.map()返回数组的新引用,所以创建了一个新的引用。虽然渲染和更新工作正常,无限渲染正在发生。

考虑添加一个依赖数组到useEffect。例如:

useEffect(() => {
/* function body */
},[props.items]);

现在useEffect回调只在props.items引用改变时运行。

旁注(与你的问题无关):在下面的代码中,

function addItem(){
let newItem = item
newItem.push({
produto: 'Skol 350ml',
preco: '1200,00',
quantidade: 'cx c/ 15 unidades'
})
setItem(newItem)
}

您应该执行let newItem = [...item],否则您不会创建item数组的新引用,并且在这种情况下setItem(newItem)基本上是无用的。

相关内容

最新更新