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;