Home > Blockchain >  How to avoid this message warning "Maximum update depth exceeded..." on NextJs
How to avoid this message warning "Maximum update depth exceeded..." on NextJs

Time:06-26

on NextJs i not understand, how useEffect work. What i need to do, to stop of receiving this warning message "Maximum update depth exceeded":

The Code bellow is the page, that call a component ListContainer, this page add a item to container.

The page 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>
    )
}

Bellow the component that handle the items, remove or add. But it works, but on console trigger warning messages about update. Component 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}
        </>
    )
}

CodePudding user response:

You are getting into an infinite loops of renders. This code is responsible:

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)
    })

This callback inside useEffect will run after every render, because there is no dependency array. That means after every render, setHTML(itemHTML) is called. And even if the constituent objects of the array itemHTML are same, a new reference of the array is created. A new reference is created because .map() returns a new reference of the array. And although render and update works correctly, infinite rendering is happening.

Consider adding a dependency array to useEffect. For example:

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

Now useEffect callback only runs if props.items reference changes.

Side note (unrelated to your question): In the below code,

  function addItem(){

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

    }

You should do let newItem = [...item], otherwise you are not creating a new reference of item array and setItem(newItem) is basically useless in that case.

  • Related