Skip to content

Instantly share code, notes, and snippets.

@ifirmawan
Created September 20, 2021 01:40
Show Gist options
  • Save ifirmawan/2acf9bec2968c570788f2291fbef33c7 to your computer and use it in GitHub Desktop.
Save ifirmawan/2acf9bec2968c570788f2291fbef33c7 to your computer and use it in GitHub Desktop.
Filtering with useEffect
import React, { useEffect, useState } from 'react';
import items from '../json/products.json'; // json file as data dummy for example.
const ProductPage = () => {
const [products, setProducts] = useState(items);
const [size, setSize] = useState(null);
const [keyword, setKeyword] = useState(null);
const [loading, setLoading] = useState(true); // Loading is true each page first load
const handleOnFiltering = (size, keyword) => {
const p = [
...products.filter((p) => {
return p.size === size && (p.name.includes(keyword) || p.description.includes(keyword) || p.price.includes(keyword));
});
];
setProducts(p);
}
useEffect((){
/**
* KEEP IN MIND
* Please add conditional updating state to avoid memory leak caused loop forever then your server is down badly.
* In this case, I'm using loading to handle conditional updating products state.
**/
if (loading) {
setLoading(false);
handleOnFiltering(size, keyword);
}
}, [loading, size, keyword]); // Add size and keyword state as subscriptions
return (
<div>
<div>
<input
type="text"
value={keyword}
onChange={(e) => {
setLoading(true);
setKeyword(e.target.value);
}}
/>
<select
onChange={(e) => {
setLoading(true);
setSize(e.target.value);
}}
value={size}
>
<option value="s">S</option>
<option value="m">M</option>
<option value="l">L</option>
<option value="xl">XL</option>
</select>
</div>
{loading
? <>Loading...</>
: (
<ul>
{products.map((p, key) => <li key={key}>{p.name} | {p.price} | {p.description}</li>)}
</ul>
)
}
</div>
)
}
export default ProductPage;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment