代码示例:
https://stackblitz.com/edit/react-filtering-hooks-search-category?embed=1&file=index.js
在上面的 StackBlitz 示例中,我尝试从搜索输入中过滤项目列表,以及通过按钮按类别过滤。我已经可以使用搜索输入和一键切换,但我正在努力使它有条件地使用多个类别选择。我坚持想出按搜索文本以及类别选择的所有组合过滤的表达式。如下图所示:
React.useEffect(() => {
const searchRegex = searchText && new RegExp(`${searchText}`, "i");
const filteredData = items.filter(
(item) =>
(!searchRegex ||
searchRegex.test(item.title) ||
!searchRegex ||
searchRegex.test(item.source)) &&
(!productsFilter || item.type === "product")
);
setFilteredItems(filteredData);
}, [searchText, productsFilter, resourceFilter, extraFilter]);
我首先删除了每个过滤器的单个状态,并创建了一个新状态,它只是将过滤器作为一个整体表示:
const [filter, setFilter] = React.useState(new Set());
选择每个过滤器后,我们可以检查 设置是否包含它。如果是,我们可以将其删除,否则可以插入:
const filterClick = (value) => {
if (filter.has(value)) {
setFilter(prevFilter => {
const newSet = new Set(prevFilter);
newSet.delete(value);
return newSet;
});
} else {
setFilter(prevFilter => {
const newSet = new Set(prevFilter);
newSet.add(value);
return newSet;
});
}
};
我们可以通过检查过滤器状态来指示切换按钮已选中:
<ToggleButton
togglable={true}
selected={filter.has("product")}
onClick={() => filterClick("product")}
>
最后,我将它与您的输入搜索相结合,以便我们可以同时过滤过滤器和输入搜索:
let filteredItems = items.filter(item => {
if (filter.size > 0 && !filter.has(item.type))
return false;
if (searchText.length > 0 && !`${item.title}${item.descriptoin}`.includes(searchText))
return false;
return true;
}).map((item, i) => <li>{item.title} <br/><span>{item.descriptoin}</span></li>);
顺便说一句:descriptoin
拼写不正确,应该是描述。
我这里有一个工作示例:
https://stackblitz.com/edit/react-filtering-hooks-search-category-fktr2w