react警告:flattenChildren(...):遇到两个具有相同密钥的孩子

IT技术 javascript reactjs select option
2021-04-01 09:27:53

有人可以解释一下如何解决这个错误

警告:flattenChildren(...):遇到两个拥有相同密钥的孩子

我在下面复制了我的代码,但由于某种原因 CodePen 没有显示错误。

var FilterOptions = React.createClass({
changeOption: function(type, e) {
var val = e.target.value;
this.props.changeOption(val, type);
},

render: function() {

return (
  <div className="filter-options">
    <div className="filter-option">
      <select id="product" name="Product" value={this.props.product} onChange={this.changeOption.bind(this, 'product')}>
      <option value=''>Product</option>
      {this.props.productOptions.map(function(option) {
        return (<option key={option}  value={option}>{option}</option>)
      })}
      </select>
  </div>
  </div>
 );
 }
 });

代码笔

作为第二个问题,我很确定我的重置应该重置选择框的值,但这也不起作用,只是重置呈现的结果 - 不确定这是否与第一个问题有关?

非常感谢任何帮助

4个回答

使用索引作为键不是一个好主意。键是 React 唯一用来识别 DOM 元素的东西。如果您将项目推入列表或删除中间的项目会发生什么?如果键与之前相同,React 假定 DOM 元素表示与之前相同的组件。但事实并非如此。来自:https : //medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

使用您要映射的每个项目中的唯一字符串作为键要好得多。喜欢的东西<option key={value.id}>,或者如果键不存在,创建通过执行类似的唯一标识符<option key={value.name + value.description}>

@Kokodoko 在这种情况下最好使用不可变数据(或至少尽量不要系统地改变您的复选框),并使用对象的哈希作为键。这是区分点、复选框等对象并创建唯一键的唯一方法。
2021-05-27 09:27:53
Arrg 但是如果 props 对象中没有任何独特的东西怎么办?就我而言,我有一排有 5 个复选框。复选框是为数组中的每个条目生成的。但它们并没有什么独特之处......
2021-06-06 09:27:53

添加索引作为值修复了这个问题。感谢@azium 的建议。

  <select id="product" name="Product" value={this.props.product} onChange={this.changeOption.bind(this, 'product')}>
      <option value=''>Product</option>
      {this.props.productOptions.map(function(option, value) {
        return (<option key={value}  value={option}>{option}</option>)
      })}
      </select>
这似乎与 React 希望你做的事情有悖常理,但它确实有效。我之前使用过一个唯一的 ID 字段,我花了一个小时才找到这个解决方案。我仍然不知道为什么它在一个简单的映射数组上使用相同的键渲染多个项目,其中 ID 绝对是唯一的。
2021-05-30 09:27:53
这是一个糟糕的答案将来,如果您使用map()另一个数组,并且索引相同,则会发生键冲突。
2021-06-04 09:27:53

我非常喜欢通过将索引与一些常量值相结合来使用键,而不是使用key={value.name + value.description}

key={'some-constant-value'+index}

这是因为我可以有意识地传递密钥,它是用于哪个组件的。例如。<ComponentA key={'compoent-a-'+i} />. 另外,我遵循这种方法是因为简单的 html 约定与我们提供的id="my-some-of-the-id"类似。

所以,即使你想使用 name 和 description 作为键,你也可以这样使用:

key={'some-constant-'+value.name+'-'+value.description}

这只是一个意见。不过,我在编写 props 值时遵循 html 约定。

实际上,您需要为每个子项指定一个唯一键,因此您需要创建另一个键,例如,如果您从数据库中获取数据,则为此创建一个新列,例如 (id),然后添加该列的值列到您的 div 或您作为键循环的内容

var FilterOptions = React.createClass({
changeOption: function(type, e) {
var val = e.target.value;
this.props.changeOption(val, type);
},

render: function() {

return (
  <div className="filter-options">
    <div className="filter-option">
      <select id="product" name="Product" value={this.props.product} onChange={this.changeOption.bind(this, 'product')}>
      <option value=''>Product</option>
      {this.props.productOptions && this.props.productOptions.map(function(option) {
        return (<option key={option.id}  value={option}>{option}</option>)
      })}
      </select>
  </div>
  </div>
 );
 }
 });

我希望这对未来的任何人都有帮助。