使用下拉菜单反应过滤项目
React filter items with dropdown
我正在学习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')
);
因为第一次选择下拉菜单时会更新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;
});
}
您的代码还有另一个考虑因素:唯一真正需要状态的组件是filterform。其他组件只需要道具。
这确实可以简化和减少您的代码。
- 仅保持表单中的状态,并且只需要将选定的筛选器保持在该状态
- 将筛选器选项+选定的筛选器传递到选项组件
- 将整个datalist+选定的筛选器传递到您的列表组件
以下代码也完全符合您的要求(从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')
);
相关文章:
- 相对于角度控制器中的另一个阵列过滤阵列项目
- 限制在角度中过滤是否会阻止在 ng 重复中加载其他项目
- 观察角度过滤项目的变化
- 如何过滤推特流API订阅源,只获取与新闻相关的项目
- 使用 bxSlider 使用显示/隐藏过滤滑块项目
- jQuery在过滤后仅导航可见项目
- 角度按条件过滤数组中的多个项目
- 使用 .filter .map .some .indexOf 等过滤项目
- 角度.js分页过滤的数据并显示总项目,而无需在视图/控制器中复制代码
- Angular:过滤多个项目
- Jquery同位素过滤淡化不匹配的项目,而不是隐藏
- 使用同位素过滤后,当项目的宽度小于3时,请更改项目的宽度
- 使用下拉菜单反应过滤项目
- 用angular js过滤项目
- JavaScript | AngularJS:根据日期过滤结果过滤项目
- 过滤jQuery可排序的项目
- AppleScript JXA过滤表与许多行相同的名称,但不同的项目
- 我应该如何创建一个项目列表,过滤下拉项目选择在引导
- 我如何格式化谷歌图表数据,以显示项目的计数,但按年过滤
- 使用 jQuery (AJAX) 过滤项目 - 请求以错误的顺序完成