Home > Software design >  How to fix a this react filter?
How to fix a this react filter?

Time:11-01

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;```

CodePudding user response:

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);
   }
}

CodePudding user response:

Try like below, I have used test data from the JSON placeholder And my App.js file

import React from 'react';
import logo from './logo.svg';
import './App.css';
import Search from "./components/Search"
function App() {
  return (
    <div className="App">
      <Search />
    </div>
  );
}

export default App;

Search component JS file:

import React from 'react';
class Search extends React.Component{
  constructor(){
    super();
    this.state = {
      data:'',
      items: []
    }
    this.filterList = this.filterList.bind(this);
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
        .then(res => res.json())
        .then(
        (result) => {
            this.setState({data: result});
        }
        )
  }

  filterList(event){
    var updatedList = this.state.data;
    console.log('-----------------',updatedList)
    updatedList = updatedList.filter(function(item){
      return item.name.toLowerCase().search(
        event.target.value.toLowerCase()) !== -1;
    });
    this.setState({items: updatedList});
  }

  componentWillMount(){
    this.setState({items: this.state.data})
  }

  render(){
      
    return (
      <div>
        <form>
        <fieldset>
        <input type="text" placeholder="Search" onChange={this.filterList}/>
        </fieldset>
        </form>
      <List items={this.state.items}/>
      </div>
    );
  }
}
class List extends React.Component{
  render(){
    return (
      <ul>
      {this.props.items && 
        this.props.items.map(function(item) {
          return <li key={item.name}>{item.name}</li>
        })
       }
      </ul>
    )  
  }
};

export default Search;
  • Related