2015-04-01 75 views
3

我使用的是反应在页面上上安装两个相同的组件,React.js混淆了“两个孩子使用相同的密钥”

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') 
); 

然后点击“一”的按钮,这是正常的,但是当我点击'two'按钮时,'two'中的一些出现在'two'中,为什么?这让我感到困惑。控制台显示:

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') 
); 

它正常工作。 发生了什么?有没有什么错误或它的错误?

回答

4

哦,我找到了真正的原因,getDefaultProps被调用一次并缓存,通过getDefaultProps()返回的任何复杂的对象将穿过的情况下,不可复制的共享,因此没有道具通过将共享相同的检查明确的值都选择框组件状态中的数组引用。 的情况下,我应该写:

getInitialState: function() { 
    var tmp = this.props.value.concat(); 
    return {checked: tmp, count: 1}; 
    }, 
2

不,这里没有错误,你渲染组件的同一实例两次,这意味着'组件'共享相同的状态,但是当你传递不同的道具组件现在有两个状态可以跟踪。

+0

谢谢你你的答案,你的意思是没有明确价值的所有组件将是相同的实例?在这种情况下,我应该为每个组件提供明确的价值? – alchemist 2015-04-01 06:09:33

+0

没有,只是在你的情况,以及如何小提琴设置。 – 2015-04-01 07:08:19

+0

@limelights所以我会如何解决这个问题?我有同样的问题,最有可能是因为你所描述的。用例是它的一个烤面包机,当一个新的通知进来我不印字的阵列到新添加到数组的开头(这样他们就可以从底部加载),所呈现的先前通知获得不同的道具,因为他们现在要在不同的地方渲染......但通知本身不会改变。 – 2015-12-10 02:35:29

1

这个问题似乎拿出了我,当我在一个列表样式设置的按键反应成分,而id的传入键不是唯一的,因为错误描述建议。

例如列表中的项目2有1

这通常是一个关键的原因是设置您的唯一ID的逻辑错误。

对于我的例子中我使用的应用程序状态的终极版店,和我设置的项目的ID是items.length + 1这是不正确的。

这导致上述two children with the same key error我。为了解决这个问题,我设置每个新项目的ID是的itemsAdded到列表中随时间变化的数字。

它类似于在ID不断递增数据库键,这样你就可以在数据库中没有的项目,由于删除它们所有,但是你下一个项目ID可能是1000

相关问题