【发布时间】:2020-05-11 05:33:09
【问题描述】:
我是 React 的新手,我正在努力在 React 上应用多个过滤器。我需要按以下条件过滤应用过滤器的车辆列表:年份、价格范围、新旧车辆。我不知道该怎么做,我有点迷失了搜索和观看教程。有人可以帮我吗?
我可以单独应用每个过滤器,但不能一起应用。我正在考虑在我的代码中添加一种过滤器。
这是我的代码:
数据:
const faixaValor = useMemo(
() => [
{ ID: 1, PriceRangeID: 1, value: '0-20', Name: 'R$0 - R$20.000' },
{ ID: 2, PriceRangeID: 2, value: '20-40', Name: 'R$20.001 - R$40.000' },
{ ID: 3, PriceRangeID: 3, value: '40-60', Name: 'R$40.001 - R$60.000' },
{ ID: 4, PriceRangeID: 4, value: '60-100', Name: 'R$60.001 - R$100.000' },
],
[]
)
const anos = useMemo(
() => [
{ ID: 1, YearID: 1, value: 2012, Name: '2012' },
{ ID: 2, YearID: 2, value: 2013, Name: '2013' },
{ ID: 3, YearID: 3, value: 2014, Name: '2014' },
{ ID: 4, YearID: 4, value: 2015, Name: '2015' },
{ ID: 5, YearID: 5, value: 2016, Name: '2016' },
{ ID: 6, YearID: 6, value: 2017, Name: '2017' },
{ ID: 7, YearID: 7, value: 2018, Name: '2018' },
],
[]
)
我的复选框:
<Checkbox
value={newChecked}
onChange={event => setNewChecked(event.target.checked)}
title="Novos"
/>
<Checkbox
value={usedChecked}
onChange={event => setUsedChecked(event.target.checked)}
title="Usados"
/>
搜索组件传递props:
<Search
priceRange={priceRange}
year={year}
newChecked={newChecked}
usedChecked={usedChecked}
/>
搜索组件:
function Search(props) {
const [loading, setLoading] = useState(true)
const [error, setError] = useState(false)
const [hasMore, setHasMore] = useState(false)
const [pageNumber, setPageNumber] = useState(1)
const [vehicles, setVehicles] = useState([])
const [search, setSearch] = useState(false)
const [filteredVehicles, setFilteredVehicles] = useState([])
const [filters, setFilters] = useState([])
const apiService = ApiService
// Infinite loading by page - 10 in 10 vehicles
useEffect(() => {
setLoading(true)
setError(false)
getVehicles()
}, [search, pageNumber])
useEffect(() => {
filterVehicles(vehicles)
}, [props])
// Observe page position
const observer = useRef()
const lastVehicleElement = useCallback(node => {
if(loading)
return
if(observer.current) observer.current.disconnect()
observer.current = new IntersectionObserver(entries => {
if(entries[0].isIntersecting && hasMore) {
setPageNumber(prevPageNumber => prevPageNumber + 1)
}
})
if(node) observer.current.observe(node)
}, [loading, hasMore])
async function getVehicles() {
await apiService.ListVehicle(pageNumber)
.then(res => {
setVehicles(prevVehicles => {
if(isFiltered) {
return [...new Set([...prevVehicles, ...res])]
} else {
return null
}
})
setHasMore(res.length > 0)
setLoading(false)
})
.catch(err => {
setError(true)
throw new Error (err.message)
})
}
async function filterVehicles(vehicles) {
/* Radius - No need 'cause of the API
if(props.radius) {}
*/
// Year
if(props.year) {
const filterYear = await vehicles.filter(
vehicle => (vehicle.YearFab == props.year)
)
await setFilters(prev => ({ ...prev, year: true }))
await setFilteredVehicles(filterYear)
console.log(filters)
}
// Price Range
if(props.priceRange) {
let prices = props.priceRange.split('-')
let priceMin = parseInt(prices[0])
let priceMax = parseInt(prices[1])
const filterMin = await vehicles.filter(
vehicle => ((parseInt(vehicle.Price)/1000) > priceMin)
)
const finalFilter = await filterMin.filter(
vehicle => ((parseInt(vehicle.Price)/1000) < priceMax)
)
await setFilteredVehicles(finalFilter)
await setFilters(prev => ({ ...prev, priceRange: true }))
console.log(filters)
}
// Both checkboxes true
if(!props.newChecked & !props.usedChecked) {
return null
} else {
// Checkbox new True
if(props.newChecked & !props.usedChecked) {
const filterNew = await vehicles.filter(
vehicle => !vehicle.KM
)
await setFilteredVehicles(filterNew)
await setFilters(prev => ({ ...prev, filterNew: true }))
}
// Checkbox used True
if(props.usedChecked & !props.newChecked) {
const filterUsed = await vehicles.filter(
vehicle => vehicle.KM
)
await setFilteredVehicles(filterUsed)
await setFilters(prev => ({ ...prev, filterUsed: true }))
}
}
if(props.newChecked & props.usedChecked) {
await setFilteredVehicles(vehicles)
await setFilters([])
}
}
function isFiltered() {
if(props.newChecked || props.usedChecked || props.year || props.priceRange) {
return true
} else {
return false
}
}
async function handleClick() {
setVehicles([])
let totalPages = 3;
for(let i=1; i <= totalPages; i++) {
await apiService.ListVehicle(i)
.then(res => {
setVehicles(prevVehicles => {
return [...new Set([...prevVehicles, ...res])]
})
})
}
filterVehicles(vehicles)
setVehicles(filteredVehicles)
setSearch(true)
}
async function handleFilter() {
setVehicles([])
setFilteredVehicles([])
}
return (
<Fragment>
<button onClick={() => handleClick()}>Buscar</button>
<button onClick={() => handleFilter()}>Limpa</button>
{ isFiltered() ? (
<div>
<h1 className="filtered">Filtrados</h1>
<div className="grid">
{ filteredVehicles.map(vehicle => (
<div className="vehicle-card-item" key={vehicle.ID}>
<ul>
<li>
<img src={vehicle.Image} alt={vehicle.Make}/>
<div className="vehicle-details">
<div className="vehicle-main-info">
<h2>{vehicle.Make} {vehicle.Model}</h2>
<h3>{vehicle.Version}</h3>
</div>
<div className="vehicle-price">
<strong>R${vehicle.Price}</strong>
</div>
<div className="year-and-km">
<h4>{vehicle.YearFab} / {vehicle.YearModel}</h4>
<h3>{vehicle.KM} km</h3>
</div>
</div>
</li>
</ul>
</div>
))
}
</div>
</div>
) : (
// { search &&
<div className="grid">
{ vehicles.map((vehicle, index) => {
if (vehicles.length === index + 1) {
return <div className="vehicle-card-item" ref={lastVehicleElement} key={vehicle.ID}>
<ul>
<li>
<img src={vehicle.Image} alt={vehicle.Make}/>
<div className="vehicle-details">
<div className="vehicle-main-info">
<h2>{vehicle.Make} {vehicle.Model}</h2>
<h3>{vehicle.Version}</h3>
</div>
<div className="vehicle-price">
<strong>R${vehicle.Price}</strong>
</div>
<div className="year-and-km">
<h4>{vehicle.YearFab} / {vehicle.YearModel}</h4>
<h3>{vehicle.KM} km</h3>
</div>
</div>
</li>
</ul>
{ loading ? ( <Loading /> ): null}
</div>
} else {
return <div className="vehicle-card-item" key={vehicle.ID}>
<ul>
<li>
<img src={vehicle.Image} alt={vehicle.Make}/>
<div className="vehicle-details">
<div className="vehicle-main-info">
<h2>{vehicle.Make} {vehicle.Model}</h2>
<h3>{vehicle.Version}</h3>
</div>
<div className="vehicle-price">
<strong>R${vehicle.Price}</strong>
</div>
<div className="year-and-km">
<h4>{vehicle.YearFab} / {vehicle.YearModel}</h4>
<h3>{vehicle.KM} km</h3>
</div>
</div>
</li>
</ul>
</div>
}
})}
</div>
)}
</Fragment>
)
}
export default Search
【问题讨论】:
标签: reactjs