Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displayed data does not update in nested loop on state

I have an object looking like this:

categories : [
    { 
        name: "General Information",
        rows: [
            {
                information1 : "",
                information2 : "",
            }
        ]
    }
]

And I am displaying the rows content using a loop like this:

{formData?.categories?.map(c => (
    <div>
        {c.name}
        {c.rows.map((row) => (
        <div>
            <input value={field.information1} />
            <textarea value={field.information2}></textarea>
            <button onClick={() => addRow(c.name)}>Add Row here</button>
        </div>
    ))}
    </div>

))}

When I press one of these buttons (that should add a row to rows array) the formData state does update, but the displayed data does not.

function addRow(category) {

    const updatedFormData = formData

    for (const cat of updatedFormData.categories) {
        if (cat.name === category) {
            cat.rows.push({
                information1 : "test",
                information2 : "this is a test"
            })
        } 
    }

    setFormData(updatedFormData)
} 
like image 303
Cyberguy Game Avatar asked Sep 04 '26 09:09

Cyberguy Game


1 Answers

In the addRow function, create a copy of formData before updating it

function addRow(category) {

    const updatedFormData = {...formData};

    // Make changes to updatedFormData

    setFormData(updatedFormData)
}

We need to create a copy before updating to let react know that the state has changed.

Consider this scenario,

const obj1 = {a : 1, b: 2};
const obj2 = obj1;
obj2.b = 12;

console.log(obj1 === obj2); // true

obj1 and obj2 point to the same object reference. Even if we changed the value of b, the reference has not changed. Similarly, when we updated the categories of formData without creating a copy, the reference had not changed, and react has no way to know that the state has been updated. So we create a new object and copy the contents of formData to it and then update the copy and set the state with the copy.

From the official docs:

State can hold any kind of JavaScript value, including objects. But you shouldn’t change objects that you hold in the React state directly. Instead, when you want to update an object, you need to create a new one (or make a copy of an existing one), and then set the state to use that copy.

like image 190
Abito Prakash Avatar answered Sep 05 '26 22:09

Abito Prakash



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!