Reputation: 91
I am trying to use update state in a react function component but it is not working. I tried following a tutorial on pluralsite and apply it to my own project. Ideally this code should be finding the product based on the ID number and replacing the total with a new value.
Unfortunately I am getting an error when setting the state. If I switch useState(productNew)
with useState(data[index])
it seems like the error doesn't appear. They seem identical in structure and I'm unsure why I'm getting this issue.
This is the error message I get in the firefox console window (the message doesn't show up in Chrome). On top of the error message, the screen appears blank:
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
Again, this happens when updating it with a new state, and the error does not occur when trying to set it to the original state value.
Are there any suggestions on how to solve this issue?
This is what the data looks like. In this example I am saving the first element of the array.
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;
}
Upvotes: 3
Views: 14140
Reputation: 3656
It looks like you are calling setState inside the body of your function component. This would cause your component to setState every time it is rendered, which then leads to another render, and another render... an infinite loop.
Instead, you should only call setState on events or within a useEffect hook.
Also, your Component needs to return some JSX, or null. It cannot return undefined.
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>
}
Upvotes: 5