'How to use useEffect? so it wont duplicates displayed products using filter function? Reactjs-redux

My data from menProducts coming from store component just loops too many. Meaning it duplicates or renders too many when using my filter function. I've read using useEffect can render it only once but I don't know how to trigger its effect.

  const [filter, setFilter] = useState('');
  const menProducts = useSelector((state) => state.menProducts);

    const SearchText = (event) => { <--- this function is for input search bar
      setFilter(event.target.value);
    }

    useEffect(() => { <--- ??
    
    }, []);

      let dataSearch = menProducts.filter(id => { <-----Filter function
      return Object.keys(id).some(key=>
          id[key].toString().toLowerCase().includes(filter.toString().toLowerCase())
      )

  return (
    <main>

      {dataSearch.map((menproduct) => ( 
          <ProductMen key={menproduct}/> <---imported <ProductMen/> component is a component that use useDispatch for store reducer and it also displayed products.
        ))}
    </main>
  )
}


Solution 1:[1]

You don't need to useEffect in this case, you just have to apply the filter at the right time like this:

const [filter, setFilter] = useState("");

const menProducts = useSelector((state) => state.menProducts);

const SearchText = (event) => {
    setFilter(event.target.value);
};

return (
    <main>
        {menProducts
            .filter((menproduct) =>
                Object.keys(menproduct).some((key) =>
                    menproduct[key]
                        .toString()
                        .toLowerCase()
                        .includes(filter.toString().toLowerCase())
                )
            )
            .map((menproduct) => (
                <ProductMen key={menproduct} />
            ))}
    </main>
);

Demo: https://stackblitz.com/edit/react-6lfqps?file=src/App.js

In the demo i've also included an alternative that use useEffect if you want to take a look at it

Solution 2:[2]

Try like this:

const [filter, setFilter] = useState("");
const menProducts = useSelector((state) => state.menProducts);

  const searchText = (event) => {
    setFilter(event.target.value);
  };

  useEffect(() => {
    const dataSearch = (filter) =>
      menProducts.filter((id) => {
        // function
      });

    dataSearch(filter);
  }, [filter]);

  return (
    <main>
      {dataSearch.map((menproduct) => ( 
          <ProductMen key={menproduct}/> <---imported <ProductMen/> component is a component that use useDispatch for store reducer and it also displayed products.
        ))}
    </main>
  )

To use the useEffect hook you have to pass a function and a dependencies array.

In this case I've used an anonymous function and inside of that I've defined the function dataSearch and on the dependencies array I've just included the filter so each time the filter value changes the useEffect gets executed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 coglialoro
Solution 2 jcobo1