我正在学习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')
);
答案 0 :(得分:8)
因为您在第一次选择下拉列表时更新了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;
});
}
答案 1 :(得分:5)
您的代码还有另一个考虑因素:唯一真正需要状态的组件是filterform。其他组件只需要道具。
这可以真正简化和减少您的代码。
以下代码也完全符合您的要求(并减少了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')
);