Skip to content
Advertisement

How to fix a this react filter?

I have created a database in firebase and I have fetch it in react, that is working correctly, but I want to include a search bar to filter the elements, my problem is that when I search for an element everything works but when I delete the text from the search input the elements do not appear again.

import { db } from "../firebase";
import { Link } from "react-router-dom";
import "../App.css";

const Productos = () => {

  const [productos, setProductos] = useState([]);

  const getLinks = async () => {
    db.collection("links").onSnapshot((querySnapshot) => {
      const docs = [];
      querySnapshot.forEach((doc) => {
        docs.push({ ...doc.data(), id: doc.id });
      });
      setProductos(docs);
    });
  };

  const handelSearch = (e) => {
    const cadena = e.target.value.toLowerCase();
    const limite = Productos.length;
    //console.log(cadena);
    let tempArray = [];
    for (let i = 0; i < limite; i++) {
      const etiquetas = productos[i].description.toLowerCase();
      const patron = new RegExp(cadena);
      const res = patron.test(etiquetas);

      if (res) {
        tempArray.push(productos[i]);
      }
    }
    setProductos(tempArray);
  };


  useEffect(() => {
    getLinks();
  }, []);


  return (
    <>
      <input
        type="text"
        placeholder="Buscar"
        className="search"
        onChange={handelSearch}
        name="busqueda"
      />
      <div className="productos" name="c" id="c">
        <div className="grid-prod">
          {productos &&
            productos.map((link) => (
              <div itemID={link} className="card mb-1" key={link.id}>
                <div className="card-body">
                  <div className="d-flex justify-content-between">
                    <div className="contenedor-img">
                      <img
                        className="img-producto"
                        alt="producto"
                        src={link.img}
                      ></img>
                    </div>
                  </div>
                  <h4 className="text-secondary titulo">{link.titulo}</h4>
                  <h1 className="text-secondary titulo">{link.categoria}</h1>
                  <Link to={"/" + link.url} rel="noopener noreferrer">
                    <button className="btn-prod">Ver producto</button>
                  </Link>
                </div>
              </div>
            ))}
        </div>
      </div>
    </>
  );
};

export default Productos;```

Advertisement

Answer

You can set another state array that keeps track of all the products.

ex:

const [productos, setProductos] = useState([]);
const [allProductos, setAllProductos] = useState([]);

const getLinks = async () => {
   db.collection("links").onSnapshot((querySnapshot) => {
      const docs = [];
      querySnapshot.forEach((doc) => {
         docs.push({ ...doc.data(), id: doc.id });
      });
      setProductos(docs);
      setAllProductos(docs);
   });
};


function handleSearchChange(event) {
   setSearchValue(event.target.value);
   search(event.target.value);
}

function search(searchValue) {
   setProductos(allProductos);
   if(searchValue != ""){
      /* perform search logic here */
      setProductos(tempArray);
   }
}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement