答案 0 :(得分:2)
你的主要问题是它不应该为空,但正如React建议的那样,它应该是未定义的或空字符串。
null
不是可接受的值的原因是因为属性只允许字符串值,而没有对象。由于null是一个对象,因此不建议使用它。然而,未定义不会添加属性(因为它未定义)。
可以在sourcecode中找到这样的原因。当select不是多值时,默认情况下,当值未定义时,第一个选项将获得selected。给定值时,它必须是可字符串的,您可以在代码here的注释部分找到
如果该值设置为undefined,则不会抱怨,正如您在此代码段中所看到的那样
class CustomList extends React.Component {
render() {
var selectedId = this.props.selectedValue;
return (
<select size="8" onChange={this.props.onChange} value={selectedId}>
{ this.props.items.map( item => <option key={item.id} value={item.id}>{item.text}</option> ) }
</select>
);
}
}
class TwoSelect extends React.Component {
constructor() {
super()
this.state = {
firstList: [
{id: 'fitem1', text: 'fvalue1'},
{id: 'fitem2', text: 'fvalue2'}
],
secondList: [
{id: 'sitem1', text: 'svalue1'},
{id: 'sitem2', text: 'svalue2'}
],
selectedValue1: undefined,
selectedValue2: undefined
}
}
render() {
return <div>
<CustomList placeholder="select" items={this.state.firstList} selectedValue={this.state.selectedValue1} onChange={(e)=>{this.selectionChanged('selectedValue1', e.target.value)}} />
<div>selectedValue1: {this.state.selectedValue1}</div>
<CustomList placeholder="" items={this.state.secondList} selectedValue={this.state.selectedValue2} onChange={(e)=>{this.selectionChanged('selectedValue2', e.target.value)}} />
<div>selectedValue2: {this.state.selectedValue2}</div>
</div>
}
selectionChanged(stateKey, value) {
this.setState({
[stateKey]: value
});
}
}
ReactDOM.render(
<TwoSelect />,
document.getElementById('container')
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
&#13;
对于一些额外的建议,没有理由让你制作完全相同的多个列表组件。这将使您的应用程序在未来非常复杂,您真的不需要这种复杂性。
尝试查看代码中可以重用的内容,然后只使用那些单个组件。
例如,您的FirstList
和SecondList
组件可以简化为例如CustomList
,然后您只需要在CustomList
中拨打TwoSelect
两次渲染方法。
class CustomList extends React.Component {
render() {
var selectedId = this.props.selectedValue;
return (
<select onChange={this.props.onChange} value={selectedId}>
{ this.props.items.map( item => <option key={item.id} value={item.id}>{item.text}</option> ) }
</select>
);
}
}
创建select
框时,大多数情况下选择了默认值,为了避免这种情况,您可以选择添加一个额外的空选项,在这种情况下会选择此选项。
如果我现在要呈现您的TwoSelect
组件,我可以更改以下内容以使您的应用程序在将来更容易维护(比如稍后会添加第三个列表; - )
render() {
return <div>
<CustomList
placeholder="select"
items={this.state.firstList}
selectedValue={this.state.selectedValue1}
onChange={(e)=>{this.selectionChanged('selectedValue1', e.target.value)}} />
<div>selectedValue1: {this.state.selectedValue1}</div>
<CustomList
placeholder=""
items={this.state.secondList}
selectedValue={this.state.selectedValue2}
onChange={(e)=>{this.selectionChanged('selectedValue2', e.target.value)}} />
<div>selectedValue2: {this.state.selectedValue2}</div>
</div>;
}
正如您所看到的,我删除了对2个处理程序的需求,现在您的选择更改了事件而不是这样:
selectionChanged(stateKey, value) {
this.setState({
[stateKey]: value
})
}
这会使stateKey成为一个字符串值,如'selectedValue1'
,正如您从上面的处理程序中的变化中看到的那样
使用jsfiddle的演示可以找到here