Reputation: 369
I have some props in the form of an array of objects that I am using to update my "items" state. I am able to loop through the objects and build objects containing the "product_id" and the "quantity". When I just console.log I can see the correct data, however when I try to update the state I get the error "Too many re-renders, react limits the number of renders to prevent an infinite-loop."
const [items, setItems] = useState(
{
product_id: 93,
quantity: 2,
},
{
product_id: 22,
variation_id: 23,
quantity: 1,
},
);
const cart = props.cart;
Object.keys(cart).forEach(function (key) {
const prod = {
product_id: cart[key].id,
quantity: cart[key].quantity,
};
setItems((currentItems) => {
return {prod, ...currentItems};
});
});
Edit My cart props is pulled from redux using the following code
function mapStateToProps(state) {
return {
cart: state.cart,
};
}
export default connect(mapStateToProps)(Checkout);
The problem is that this prop has more attributes than just the quantity and id that I need.
Upvotes: 1
Views: 3066
Reputation: 1145
You don't need to set the state again and again in a loop. Rather, just loop on the array, get the items and finally set the state
const [items, setItems] = React.useState(
{
product_id: 93,
quantity: 2
},
{
product_id: 22,
variation_id: 23,
quantity: 1
}
);
const { cart } = props;
useEffect(() => {
const products = Object.entries(cart).map(([key, { id, quantity }]) => ({
product_id: id,
quantity: quantity
}));
setItems(currentItems => ({ ...products, ...currentItems }));
}, [cart]);
Upvotes: 3
Reputation: 984
You should use an array or an object as the state. you are passing two separate objects to useState, wrap them in an object with proper keys. or use an array.
it seems you have forgotten to add a wrap your initial object inside curly braces.
const [items, setItems] = useState([
{
product_id: 93,
quantity: 2,
},
{
product_id: 22,
variation_id: 23,
quantity: 1,
},
]);
then
return [prod, ...currentItems];
as a suggestion:
it's better to make new objects and set them in the state all at once.
const objectsToAdd = Object.values(cart).map(function (cartItem) {
return {
product_id: cartItem.id,
quantity: cartItem.quantity,
};
});
setItems((currentItems) => {
return [...objectsToAdd, ...currentItems];
})
Upvotes: 2