HelpANoobOut
HelpANoobOut

Reputation: 223

Filtering data using react hooks

Hey guys I've been learning react for a few weeks now so please be easy on me =). When I was using dummy data, the filter function worked and showed the correct products in the category. I built the back end api using django and now my filter function doesn't work anymore. It does filter but the data totally disappears after pressing the different filter buttons. Can anyone help?

import React, { useState, useEffect } from "react";
import axios from "axios";
import ButtonList from "../components/ButtonList";
import ProductList from "../components/ProductList";

const ProductPage = () => {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const fetchProduct = async () => {
      const { data } = await axios.get("/api/products/");
      setProducts(data);
    };
    fetchProduct();
  }, []);

  const filter = (button) => {
    if (button === "All") {
      setProducts(products);
      return;
    }

    const filteredData = products.filter(
      (products) => products.category === button
    );
    setProducts(filteredData);
  };

  return (
    <div>
      <ButtonList onClickFilter={filter} />
      <ProductList product={products} />
    </div>
  );
};
export default ProductPage;

Upvotes: 2

Views: 7891

Answers (2)

Ajeet Shah
Ajeet Shah

Reputation: 19863

You are losing the original list of products as your setting filtered data in it. So, currently there is no way to get the original products list back.

To fix it, you can set search in a state and use that to filter the products. This way original data is always present in products but filtered data is used for rendering the list:

const ProductPage = () => {
  const [products, setProducts] = useState([])
  const [search, setSearch] = useState('ALL') // New State for search

  // ...

  const filter = (button) => {
    setSearch(button)
  }

  return (
    <div>
      <ButtonList onClickFilter={filter} />
      <ProductList
        product={products.filter((p) => search === 'ALL' || p.category === search)}
      />
    </div>
  )
}

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 371138

Right now, after filtering, you're losing the full products array information permanently, since it only exists in the stateful products variable that setProducts will essentially overwrite. Add another state, one which contains the full products, and filter off of it instead.

const ProductPage = () => {
  const [fullProducts, setFullProducts] = useState([]);
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const fetchProduct = async () => {
      const { data } = await axios.get("/api/products/");
      setFullProducts(data);
    };
    fetchProduct();
  }, []);

  const filter = (button) => {
    if (button === "All") {
      setProducts(fullProducts);
      return;
    }

    const filteredData = fullProducts.filter(
      (product) => product.category === button
    );
    setProducts(filteredData);
  };

  return (
    <div>
      <ButtonList onClickFilter={filter} />
      <ProductList product={products} />
    </div>
  );
};

Upvotes: 1

Related Questions