reactjs - 如何使过滤和搜索协同工作?
问题描述
我有一个组件:
export default class Shop extends PureComponent {
state = {
search: "",
filters: [],
items: json
};
onFilterChange = ( event ) => {
const checkboxes = [...event.currentTarget.closest(".filter").getElementsByTagName("input")]
const filters = [];
checkboxes.map(checkbox => {
if (checkbox.checked) {
filters.push(checkbox.name);
}
});
this.setState({ filters }, this.filtredInput);
}
filtredInput() {
let items = json
if (this.state.filters.length !== 0) {
items = items.filter(element => this.state.filters.every(key => element[key]));
}
if (this.state.search.length !== 0) {
items = items.filter(word =>
word.name.toLocaleLowerCase().indexOf(this.state.search.toLocaleLowerCase()) !== -1
)
}
this.setState( {items} )
}
onSearchChange = ( {currentTarget} ) => {
const search = currentTarget.value
this.setState({ search }, this.filtredInput() )
}
render() {
return (
<div>
<div className="navigation">
<Filter
onFilterChange={this.onFilterChange}
/>
<Search
onSearchChange={this.onSearchChange}
/>
</div>
<Filtered
items={this.state.items}
updateShoppingBasket={this.updateShoppingBasket}
/>
</div>
)
}
}
帮助组织逻辑,使搜索和过滤器同时工作。就个人而言,一切正常。但在当前版本中,搜索工作好像有延迟(显然,代码在设置状态之前工作),但我不确定是否有其他错误。React中如何正确组织过滤器+搜索的逻辑?
解决方案
通过以不同的方式思考数据,您可以让这一切变得更轻松。如果您要求始终存储最新的过滤数据,那么这将不起作用。我在这里包含了一个自定义代码示例(包括示例所依赖的组件):https ://codesandbox.io/s/hardcore-cohen-sg263?file=/src/App.js
我喜欢考虑我们需要存储以执行操作的三段数据。
- 搜索词
- 过滤器列表
- 我们要过滤和搜索的项目列表
如果需要,我们可以从 API 下载项目列表,这样我们就可以通过过滤和替换来确保我们永远不会丢失数据。
export default class App extends React.Component {
/*
there are three things we store
1. the current search term
2. the current list of filters
3. the entire list of data we want to search and filter through
(this can start as an empty array and then be filled with data from an API)
*/
state = {
term: "",
filters: [],
list: [
{
color: "red",
name: "car"
},
{
color: "blue",
name: "plane"
},
{
color: "red",
name: "boat"
}
]
};
/* This handles toggling filters, when the filter is clicked it will check
the array and add it if it isn't there.
*/
toggleFilter = filter => {
if (this.state.filters.includes(filter)) {
this.setState({
filters: this.state.filters.filter(item => item !== filter)
});
} else {
this.setState({
filters: [...this.state.filters, filter]
});
}
};
updateTerm = term => {
this.setState({
term
});
};
/* selector function to filter a list of items */
applyFilters = list => {
if (this.state.filters.length === 0) {
return list;
}
return list.filter(item => this.state.filters.includes(item.color));
};
/* search function to filter for the search term */
applySearch = list => {
if (this.state.term === "") {
return list;
}
return list.filter(item => item.name.startsWith(this.state.term));
};
render() {
/* we can filter the list and then search through the filtered list */
const filteredItems = this.applyFilters(this.state.list);
const searchedItems = this.applySearch(filteredItems);
/* we pass the filtered items to the list component */
return (
<>
<Filters onChange={this.toggleFilter} />
<Search term={this.state.term} onChange={this.updateTerm} />
<List items={searchedItems} />
</>
);
}
}
希望这有助于为 React 建立一个不同的心智模型。我故意避免让过滤器成为受控组件,而只是为了向您展示渲染函数中的过滤器。始终开放讨论。让我知道事情的后续。
推荐阅读
- git - 克隆 git 存储库时出现 SSL 证书错误
- amazon-web-services - 当 SQS 消息发送到死信队列时如何生成警报?
- jenkins-pipeline - Cloudbees Jenkins:在不同的 Jenkins 实例之间触发下游作业
- python - anaconda/spyder scikit 学习更新 0.21.3 到 0.22.2
- swift - 无法在领域中的日期后快速过滤
- asp.net-core - SwaggerUI 未构建 - 浏览器 ASP.NET Core API 中的空白页面
- android - 如何动态设置导航菜单?
- python - 这是功能还是错误?Windows 10 python time.sleep() 挂起时时钟翻转到午夜
- javascript - 不仅在开始时自动完成文本中间
- kotlin - 父挂起函数内部的这些挂起函数会按顺序运行吗?