javascript 使用下拉菜单反应过滤器项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33613504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React filter items with dropdown
提问by cocoa
I'm learning React and wanted to filter a list using a dropdown. I've almost got it but I can only click the drop down once and then the list will go empty. I'm pretty sure it's because I'm filtering the list and then it returns the list with the filtered items. But I'm not sure how to change that.
我正在学习 React 并想使用下拉列表过滤列表。我几乎已经知道了,但我只能单击一次下拉列表,然后列表将变为空。我很确定这是因为我正在过滤列表,然后它返回带有过滤项目的列表。但我不确定如何改变它。
var filterData = [
{ name: 'Matthew', sex: 'male' },
{ name: 'Amanda', sex: 'female' }
];
var FilterForm = React.createClass({
getInitialState: function() {
return {
data: this.props.data,
sex: ''
}
},
handleChange: function(val) {
// problem is here
var filteredData = this.state.data.filter(function(item) {
return item.sex === val;
});
this.setState({sex: val});
this.setState({data: filteredData});
console.log(filteredData);
},
render: function() {
return (
<div className="filter-form">
<h1>Filter Form</h1>
<FilterOptions data={this.state.data} changeOption={this.handleChange} />
<FilterItems data={this.state.data} />
</div>
);
}
});
var FilterOptions = React.createClass({
getInitialState: function() {
return {
data: this.props.data,
sex: ''
}
},
handleChange: function(e) {
var val = e.target.value;
this.setState({bender: val});
this.props.changeOption(val);
},
render: function() {
return (
<select id="sex" value={this.state.sex} onChange={this.handleChange}>
<option value=""></option>
<option value="male">male</option>
<option value="female">female</option>
</select>
);
}
});
var FilterItems = React.createClass({
getInitialState: function() {
return {
data: this.props.data
}
},
render: function() {
return (
<div className="filter-item">
{this.props.data.map(function(item) {
return (
<div>{item.name}</div>
);
})}
</div>
);
}
});
React.render(
<FilterForm data={filterData} />,
document.getElementById('app')
);
回答by Phi Nguyen
Because your this.state.data
is updated when you selected the drop-down at the first time. You should use this.props.data
as the searching source You can change like this :
因为您this.state.data
在第一次选择下拉菜单时已更新。您应该使用this.props.data
作为搜索源您可以这样更改:
handleChange: function(val) {
this.setState({sex: val});
var filteredData;
if(val == ""){
filteredData = this.props.data;
}else{
filteredData = this.props.data.filter(function(item) {
return item.sex === val;
});
}
回答by wintvelt
There another consideration for your code as well: the only component that really needs state is the filterform. The other components only need props.
您的代码还有另一个考虑因素:真正需要状态的唯一组件是 filterform。其他组件只需要道具。
This can really simplify and reduce your code.
这确实可以简化和减少您的代码。
- keep state in form only, and you only need to keep the selected filter in the state
- pass the filter options + selected filter to your options component
- pass the entire datalist + selected filter to your list component.
- 仅在表单中保持状态,并且您只需要将选中的过滤器保持在状态
- 将过滤器选项 + 选定的过滤器传递给您的选项组件
- 将整个数据列表 + 选定的过滤器传递给您的列表组件。
The following code also does exactly what you want (and reduces from 73 to 65 lines of code):
以下代码也完全符合您的要求(并将代码从 73 行减少到 65 行):
var data = [
{ name: 'Matthew', sex: 'male' },
{ name: 'Amanda', sex: 'female' }
];
var FilterForm = React.createClass({
getInitialState: function() {
return {
sex: ''
}
},
handleChange: function(val) {
this.setState({sex: val});
console.log(val);
},
render: function() {
// create list of options from input data (based on sex)
var optionsArray=this.props.data.map((item) => { return item.sex });
optionsArray.unshift("");
return (
<div className="filter-form">
<h1>Filter Form</h1>
<FilterOptions options={optionsArray} selected={this.state.sex} changeOption={this.handleChange} />
<FilterItems data={this.props.data} filter={this.state.sex} />
</div>
);
}
});
var FilterOptions = React.createClass({
handleChange: function(e) {
var val = e.target.value;
this.props.changeOption(val);
},
render: function() {
var selectedOption = this.props.selected;
return (
<select id="sex" value={selectedOption} onChange={this.handleChange}>
{this.props.options.map(option => {
return <option key={option} value={option} selected={(option.value == selectedOption)}>{option}</option>;
})}
</select>
);
}
});
var FilterItems = React.createClass({
render: function() {
var filter = this.props.filter;
var filteredData = this.props.data.filter((item) => {
return (!filter || item.sex == filter)
});
return (
<div className="filter-item">
{filteredData.map(function(item) {
return (
<div>{item.name}</div>
);
})}
</div>
);
}
});
React.render(
<FilterForm data={data} />,
document.getElementById('app')
);