我不是专家,我知道我在这里做错了什么,但我束手无策。我正在尝试使用 UseState 和 useEffect 在 React 中创建多个过滤器。
-我想要一个搜索输入来过滤标题和描述中的搜索——我想知道为什么它只查看描述?
-为 price 添加 data.filter 也是一个大问题。在您输入最低价格之前,它不会显示任何产品。
*********************************网格组件
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { BsFillGridFill } from 'react-icons/bs';
import { FaThList } from 'react-icons/fa';
import SingleList from '../products/SingleList';
import Card from '../products/Card';
import SideFilter from './SideFilter';
const GridList = (props) => {
//select between grid or list
const [choice, setChoice] = useState(true);
// search input
const [search, setSearch] = useState('');
// minPrice
const [minPrice, setMinPrice] = useState('');
// max price
const [maxPrice, setMaxPrice] = useState('');
// filter the products coming through
const [filteredData, setFilteredData] = useState([]);
// filters
const [data, setData] = useState([]);
// to show loading boyeeeeee
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
const fetchData = async () => {
const result = await axios.get('https://fakestoreapi.com/products');
setData(result.data);
setLoading(false);
};
fetchData();
}, []);
useEffect(() => {
let filteredSearch = () => {
setFilteredData(
data.filter((data) => {
return (data.title && data.description)
.toLowerCase()
.toLowerCase()
.includes(search.toLowerCase()) && data.price >= minPrice;
})
);
};
filteredSearch();
}, [search, minPrice, maxPrice, data]);
const onSearchChange = (e) => setSearch(e.target.value);
const onMinPriceChange = (e) => setMinPrice(e.target.value);
return (
<div className='choice-div'>
<SideFilter
onSearchChange={onSearchChange}
onMinPriceChange={onMinPriceChange}
/>
<div className='grid-list-choice'>
<div className='box-choice' onClick={() => setChoice(true)}>
<BsFillGridFill />
</div>
<div className='box-choice' onClick={() => setChoice(false)}>
<FaThList />
</div>
</div>
<div className='grid-or-list'>
{loading && <p>Loading...</p>}
<div className={`grid ${!choice ? 'grid-chosen' : ''}`}>
<div className='product-grid'>
{filteredData.map((d) => (
<Card
key={d.id}
productImage={d.image}
productPrice={d.price}
productTitle={d.title}
/>
))}
</div>
</div>
<div className={`list ${choice ? 'grid-chosen' : ''}`}>
<div className='productList'>
{filteredData.map((d) => (
<SingleList
key={d.id}
listImage={d.image}
listPrice={d.price}
listTitle={d.title}
/>
))}
</div>
</div>
</div>
</div>
);
};
export default GridList;
*************************** 过滤器组件
import React from 'react';
const SideFilter = (props) => {
return (
<div className='side-filter'>
<input
className='search-input'
type='text'
placeholder='Search'
onChange={props.onSearchChange}
/>
<input
className='search-input'
type='text'
placeholder='Minimum Price'
onChange={props.onMinPriceChange}
/>
</div>
);
};
export default SideFilter;
我可能错了,但看起来你的过滤器回调中的 return 语句有问题。看起来您在 (data.title && data.desc) 上调用 .toLowerCase 两次,然后检查它是否包含您要搜索的参数。如果我们在方括号内的两个元素上使用逻辑与运算符,我认为 Javascript 会返回最后一个元素。因此,在 (data.title && data.description) 的情况下,这将简单地返回 data.description,然后您可以根据它调用 .toLowerCase。这可以解释为什么您可能只能通过描述获得结果。尝试像这样分离搜索:
return data.title && data.description && data.title.includes(...) && data.description.includes(...) && data.price >= minPrice && data.price <= maxPrice;
为此,我通常将所有搜索字段组合成一个字符串并对其应用过滤器,即:
data.filter((data) => {
if (
`${data.title.toLowerCase()}${data.description.toLowerCase()}`
.includes(search.toLowerCase())
&& data.price >= minPrice
) return true
return false
})
如果你希望价格可以为空:
data.filter((data) => {
if (
`${data.title.toLowerCase()}${data.description.toLowerCase()}`
.includes(search.toLowerCase())
&& (minPrice
? data.price >= minPrice
: true)
) return true
return false
})