how do I modify a state without overwriting it
I have a search bar, and once the user enters any word or words (eg: "green plant") I split those words with space and array would look like words = ["green","plant"]. Now, I need to use each word as a value to my filter api which indeed returns the data that has the search word in the title or name.
The issue is that, each time it calls it overwrites the existing state so that whatever data I got for word "green" is overwritten with the next api call for "plant".
My Code for setting them,
if (response.status === 200) {
setProduct(response.data.product)
}
I also tried to use spread operators, if (response.status === 200) { setProduct([...product,response.data.product]) }
and also tried,
if (response.status === 200) {
setProduct((prevProducts) => [
...prevProducts.product,
response.data.product,
]);
}
Error for the above TypeError: Invalid attempt to spread non-iterable instance
response.data.product:
[
{
"_id":"61daa6401d0f202659003c12",
"name":"TIMA - Top Class Blanket",
"originalPrice":1599,
"storePrice":1500,
"discount":6.2,
"description":"Single Blanket , Size: 226*150 cm",
"category":"blankets",
"quantity":10
},
{
"_id":"61daa6401d0f2026592eef3",
"name":"Flora Bed",
"originalPrice":2599,
"storePrice":1500,
"discount":7,
"description":"Bed , Size: 226*150 cm",
"category":"bed",
"quantity":10
}
]
Solution 1:
You're most likely encountering a closure issue, where you are looping through the two API calls, but those get initialized with the same state A.
This would mean that when you want to update the state from A->B in the first call, then B->C in the second, what actually happens is that you get A->B followed by A->C, without the changes from B.
I recommend using the Promise.all
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) to await
for all results, then set your state at once. If you really want to do it sequentially, then make sure to await
the first one, set your state after it, then do the same with the second one. For this latter solution (not recommended), make sure to use the callback setProduct((prev) => [...prev, newValue])
.