我正在做一个React应用程序,它从后端带来与产品相关的数据,在一个电子商务或商店类型的视图中显示产品,我开发了一个逻辑来过滤根据过滤器参数显示的产品,所以只有匹配过滤器的产品才会被呈现,问题是我不知道如何在选择过滤器时更新它们的值,关于视图被更新但是过滤器的值继续显示被过滤的旧数据。
我现在的密码是
import React ,{useState} from 'react';
import { Card, Breadcrumb, BreadcrumbItem, CardBody} from 'reactstrap';
import {Link} from 'react-router-dom';
// import { Loading } from './LoadingComponent';
import {baseUrl} from '../../shared/baseUrl';
function formatMoney(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
}
function RenderStoreItem ({product}) {
//this is a const to retrieve the images that are stored on images/products
const imagePath = baseUrl + "images/products/";
return (
<Card className='product-card'>
<Link to={ `/store/${product._id}` } style={{textDecoration:"none",color:"black"}}>
<img
className='card-img-top-store'
src={imagePath + product.marca + "_" + product.linea + "_" + product.modelo + "/" + product.images[0] }
alt={product.marca} />
{/* display the CardTitle inside CardImgOverlay in the right bottom corner */}
<CardBody>
<h3 >${formatMoney(product.price)}</h3>
<div>
<h5>{product.marca} - {product.linea}</h5>
</div>
<h5>{product.modelo}</h5>
</CardBody>
</Link>
</Card>
);
}
const Store= ({products}) =>{
//this are the filters to apply to the products, so just the products that match the filters will be displayed
// but if the filter is empty then all the products will be displayed
const [filter, setFilter] = useState({
marca: '',
linea: '',
modelo: 0
});
// this function is called when the user select a filter
// the filter is stored in the state filter
// when a filter is selected the products are filtered automatically, no need to click a button
const handleFilter = (event) => {
const target = event.target;
const value = target.value;
const name = target.name;
setFilter({
...filter,
[name]: value
});
}
// this function is called when the user click the button to clear the filters
// the filter is set to empty
const clearFilter = () => {
setFilter({
marca: '',
linea: '',
modelo: 0
});
}
// get distinc values
const distinctValues = (array, key) => {
const values = array.map((product) => product[key]);
const distinctValues = [...new Set(values)];
return distinctValues;
}
// when a filter is selected the products are filtered automatically, no need to click a button
// the products are filtered by any of the filter selected
// taking into account that if the filter is empty then all the products will be displayed and that marca is a String, linea is a String and modelo is a number
const filteredProducts = products.products.filter((product) => {
if (filter.marca === '' && filter.linea === '' && filter.modelo === 0) {
return product;
} else if (filter.marca !== '' && filter.linea === '' && filter.modelo === 0) {
return product.marca === filter.marca;
} else if (filter.marca === '' && filter.linea !== '' && filter.modelo === 0) {
return product.linea === filter.linea;
} else if (filter.marca === '' && filter.linea === '' && filter.modelo !== 0) {
return product.modelo == filter.modelo;
} else if (filter.marca !== '' && filter.linea !== '' && filter.modelo === 0) {
return product.marca === filter.marca && product.linea === filter.linea;
} else if (filter.marca !== '' && filter.linea === '' && filter.modelo !== 0) {
return product.marca === filter.marca && product.modelo == filter.modelo;
} else if (filter.marca === '' && filter.linea !== '' && filter.modelo !== 0) {
return product.linea === filter.linea && product.modelo == filter.modelo;
} else if (filter.marca !== '' && filter.linea !== '' && filter.modelo !== 0) {
return product.marca === filter.marca && product.linea === filter.linea && product.modelo == filter.modelo;
}
});
const store= filteredProducts.map((product) => {
return (
<div key={product.id} id = 'products' className="col-12 col-md-4 py-2">
<RenderStoreItem product={product}/>
</div>
);
});
return (
<div className="container product">
<div className="row">
<Breadcrumb>
<BreadcrumbItem><Link to="/home">Inicio</Link></BreadcrumbItem>
<BreadcrumbItem active>Product</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>Store</h3>
<hr />
</div>
</div>
<div className="row">
<div className='col-2'>
{/* here will be the filters selected, will show the data from the products available in the options*/}
<div className='row'>
<div className='col-12'>
// HERE are the filters that must be updated
<h5>Filtros</h5>
<div className='row'>
<div className='col-12'>
<label htmlFor='marca'>Marca</label>
<select className='form-control' name='marca' id='marca' onChange={handleFilter}>
<option value=''>Todas</option>
{/* display distinct values */}
{distinctValues(products.products, 'marca').map((marca) => {
return (
<option key={marca} value={marca}>{marca}</option>
);
})}
</select>
</div>
<div className='col-12'>
<label htmlFor='linea'>Linea</label>
<select className='form-control' name='linea' id='linea' onChange={handleFilter}>
<option value=''>Todas</option>
{/* display distinct values and next to it the frequency(number of occurences represented by countDistinctValues)*/}
{distinctValues(products.products, 'linea').map((linea) => {
return (
<option key={linea} value={linea}>{linea}</option>
);
})}
</select>
</div>
<div className='col-12'>
<label htmlFor='modelo'>Modelo</label>
<select className='form-control' name='modelo' id='modelo' onChange={handleFilter}>
<option value=''>Todos</option>
{/* display distinct values and next to it the frequency(number of occurences represented by countDistinctValues)*/}
{distinctValues(products.products, 'modelo').map((modelo) => {
return (
<option key={modelo} value={modelo}>{modelo}</option>
);
})}
</select>
</div>
</div>
</div>
</div>
</div>
<div className='col-10'>
<div className='row'>
{store}
</div>
</div>
</div>
</div>
);
}
export default Store;
当选择了一个筛选器并更新了视图时,如何更新筛选器中显示的数据,以使筛选的数据不再显示在筛选器中?
2条答案
按热度按时间6rqinv9w1#
您可以只使用将要显示的产品来构建选择元素,以便只显示可用选项,而不是使用所有产品来构建选择元素,下面是一个示例:
在这里,我使用了
distinctValues(filteredProducts, 'linea').map(..)
而不是distinctValues(products.products, 'linea').map(..)
a9wyjsp72#
要在选择过滤器时更新过滤器的值,可以使用“useEffect”钩子监听“filter”状态的变化并更新过滤器的值=〉
在“useEffect”钩子中,您可以使用“getElementById”获取过滤器的元素,并通过.value属性更新它们的值。
让我知道,如果它清楚或我不明白你的问题
编辑:
第二备选办法
另一种方法是在过滤器元素中添加一个onChange事件(例如,“,“)。2然后你可以使用这个事件来调用你定义的handleFilter函数。
像这样=〉
型