skip to Main Content

I have a component that loads all products on component load. The component also has a search functionality that takes user input and querys database for products based on user input. Search results should replace any products that were initially loaded by the component. Below is the load and search functionality.

The problem I am seeing is that the search function does not replace the loaded products, but it appends any products returned by the search to the already load product list.

  const [products, setProducts] = useState([]);
  const [page, setPage] = useState(1);
  const [limit] = useState(100);
  const [searchQuery, setSearchQuery] = useState('');

  useEffect(() => {
    const loadProducts = async () => {
      console.log('Fetching products for page:', page);
      try {
        const data = await fetchProducts(page, limit);
        console.log('Fetched products:', data);
        setProducts(prevProducts => [...prevProducts, ...data.products]);
      } catch (err) {
        console.error('Error fetching products:', err);
      }
    };
    loadProducts();
  }, [page, limit]);

  const handleSearch = async () => {
    console.log('Searching for products with query:', searchQuery);
    try {
      const data = await searchProducts(searchQuery);
      setProducts(data.products);  
      setPage(1);
    } catch (err) {
      console.error('Error searching for products:', err);
    }
  };

2

Answers


  1. setPage(1) causes page state to change. Since page changes and a re-render happens, the first useEffect runs (because it is included in the dependency). In the first useEffect products are appended – setProducts(prevProducts => [...prevProducts, ...data.products]);.

    The first useEffect callback also fetches products, based on pagination I think. We probably want to check if page number is 1 and queryString is not empty, then we do not need to run the first useEffect logic. Use an if condition.

    If page is 1 and queryString is empty you might want to run the effect because I assume that is how you load more data.

    Login or Signup to reply.
  2. The issue is You are using setPage(1) after the setProducts(data.products); inside the handleSearch method.

    This setPage(1) agin trigger the useEffect and call the loadProducts method

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search