The object I want to edit gets edited in JSON format, but only previous data gets displayed in the browser. I use these hooks to get a list of products from local storage
const Cart = () => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(()=>{
setProducts(loadCart());
setLoading(false)
},[])
Then I map all of the objects
const mapProducts = (products) => {
return (
<>
{products.map((product) => {
return (
<>
<div className="cart-detail">
<h4>{product.name} - {product.price}$
/ total: {product.price * product.amount}$</h4>
<h4>{product.amount}</h4>
<button onClick={() => incrementAmount(product)}>+</button>
</div>
</>
)
})}
</>
)
}
return (
<Base title="Cart">
{loading && <h1>Loading...</h1>}
{!loading && mapProducts(products)}
</Base>
)
incrementAmount()
function looks like that:
const incrementAmount = (product) => {
let tempList = products
for (let i = 0; i < tempList.length; i++) {
if (tempList[i].id === product.id) {
tempList[i].amount++;
}
}
setProducts(tempList)
}
From what I see in the console, the array looks fine and the object I wanted to edit got edited. FE: I had an object {name:"hoodie", amount:3} after clicking "+" button it changes properly to {name:"hoodie", amount:4} (in both products
and tempList
) but in console only, in the document it still displays product.amount
as 3 and I have no idea why
Instead of pass an object to setState
you can pass a function and when you have an object into the state that you want to keep old values you must use a function.
Because state
may be updated asynchronously, you should not rely on their values for calculating the next state.
You must change the incrementAmount()
function like this:
const incrementAmount = (product) => {
setProducts(prevState => {
const newState = [...prevState];
for (let i = 0; i < newState.length; i++) {
if (newState[i].id === product.id) {
newState[i].amount++;
}
}
return newState;
});
}