Reputation: 81
I have a state set as
const [filteredProducts, setFilteredProducts] = useState([]);
I want to be able to append to the end of that state. I am currently trying
products.forEach((product) => {
if (product.category === category) {
setFilteredProducts([...filteredProducts, product]);
}
});
It it looping through the products array correctly. I can even log the product after the setFilteredProducts and it logs the correct ones I want. I am calling this with an onClick.
Upvotes: 3
Views: 11485
Reputation: 126
The problem is, that setFilteredProducts
doesn't immediately affect products. It's React's job to decide when to update the state. So when you loop over products, you'll probably ending up adding just the last item, because filteredProducts
wasn't updated yet.
What you can do, is preparing an array of products to add:
const productsToAdd = products.filter(product => product.category === category);
And then append them:
setFilteredProducts([...products, ...productsToAdd]);
Upvotes: 0
Reputation: 46
I think you want what the ES6 built-in function does. You can rewrite your code to give you the the products that match the category like this:
const filteringTheProducts = products.filter(product => {
return product.category === category
})
setFilteredProducts(filteringTheProducts)
The result of the filtering will be the array of all the products that match that criteria.
Here is the documentation for .filter() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Upvotes: 0
Reputation: 4070
You would only append the last match to the existing filteredProducts
array.
You can add all matches like so:
setFilteredProducts([...filteredProducts, ...products.filter((product) => product.category === category)]);
Upvotes: 1
Reputation: 7465
I'd recommend you do this in 2 steps:
Create an array of the new products you plan to add
let productsToAdd = [];
products.forEach((product) => {
if (product.category === category) {
productsToAdd.push(product);
}
});
Then combine the arrays and set state
setFilteredProducts([...filteredProducts, ...productsToAdd]);
Upvotes: 0
Reputation: 36989
Find all the products you want to add:
const productsToAdd = products.filter(product => product.category === category)
Then append them
setFilteredProducts((currentFilteredProducts) => ([...currentFilteredProducts, ...productsToAdd]));
The issue with your example is that filteredProducts
may get stale after the first iteration. setFilteredProducts
will not run synchronously, and filteredProducts
keep the original value, until the re-render happen.
Upvotes: 5