我正在使用反应在页面上安装两个相同的组件,
var SelectBox = React.createClass({
getDefaultProps: function() {
return {
value: []
};
},
getInitialState: function() {
return {checked: this.props.value,count: 1};
},
handleClick: function() {
var opt = this.state.checked;
opt.push({id: this.state.count, name: this.state.count});
this.setState({checked: opt, count: this.state.count + 1});
},
render: function() {
var that = this;
var options = this.state.checked.map(item => <option key={'checked-' + that.props.name + item.id} value={item.id}>{item.name}</option>);
return (
<div>
<select multiple={true}>
{options}
</select>
<button type="button" onClick={this.handleClick}>add</button>
</div>
);
}
});
React.render(
<SelectBox name='one'/>,
document.getElementById('one')
);
React.render(
<SelectBox name='two'/>,
document.getElementById('two')
);
然后点击&#39; one&#39;的按钮,好吧,但是当我点击&#39; two&#39;的一些按钮时,&#39; one&#39; 39;在&#39;两个&#39;中出现,为什么?这让我感到困惑。控制台显示:
Warning: flattenChildren(...): Encountered two children with the same key, `.$checked-two1`. Child keys must be unique; when two children share a key, only the first child will be used.
但只是做一些改变
var a = [{id: 5, name: 5}];
React.render(
<SelectBox name='one' value={a}/>,
document.getElementById('one')
);
它正常工作。 发生了什么?有什么不对或是它的错误吗?
答案 0 :(得分:4)
哦,我发现真正的原因,getDefaultProps
被调用一次并缓存,getDefaultProps()
返回的任何复杂对象将在实例之间共享,而不是复制,因此所有SelectBox组件都没有显式值prop传递将在状态中共享相同的已检查数组引用。
在这种情况下,我应该写:
getInitialState: function() {
var tmp = this.props.value.concat();
return {checked: tmp, count: 1};
},
答案 1 :(得分:2)
不,这里没有错误,你要渲染两次组件的相同实例,这意味着&#39;组件&#39;共享相同的状态但是当你传递不同的道具时,组件现在会有两个状态来跟踪。
答案 2 :(得分:1)
当我在列表样式的反应组件中设置键时,似乎出现了这个问题,并且传递给键的id不是唯一的,正如错误描述所示。
例如 2个列表项的密钥为1.
这通常是由于设置您的唯一ID的逻辑错误。
对于我的示例,我在应用程序状态中使用了redux存储,并且我将项目的id设置为items.length + 1
这是不正确的。
这导致我two children with the same key error
以上。要解决此问题,我会将每个新项目的ID设置为列表中itemsAdded
的数量。
它与数据库中的密钥类似,其中id保持递增,因此您可以在数据库中没有任何项目,因为它们全部删除,但是下一个项目的ID可能是1000。