可以在实例化后添加React Keys吗?

时间:2016-04-20 01:56:20

标签: javascript reactjs functional-programming react-jsx jsx

我正在制作React Elements的集合并展示它们;接下来是一个简单的例子,用于构建仅如何修改预先存在的实例化元素的问题。

var c = [
  <div>A</div>,
  <div>B</div>,
  // ...
  <div>Z</div>
];

var ListComponents = React.createClass({
    render: function() {
        return <div>{c}</div>;
    }
});

ReactDOM.render(<ListComponents/>, document.getElementById('root'));

虽然上面的代码“有效”,但它会呈现一个我不想忽略的控制台消息:

  

警告:数组或迭代器中的每个子节点都应该有一个唯一的“key”prop。   检查`ListComponents`的render方法。   有关详细信息,请参阅https://fb.me/react-warning-keys。

从表面上看,我可以为key="…"中的每个元素添加一个唯一的c字符串,然后完成。

然而,这看起来相当冗长,特别是因为我在索引数组和函数语言中有数据,理论上可以为每个键分配其匹配的索引值,而无需手动将其作为源文字输入。

我很乐意能够做到这一点......

c.forEach( (e,i) => e.key = i );        // ...or call some setter

什么是*正确的*反应方式 - 并且 - 保持代码清洁?


附录: ...对于好奇的人或者只想说添加关键字段的人......

我正在使用的集合实际上是一个元组数组,包含元数据和相应的React元素,自定义组件或一些巨大的JSX块。上面的例子过分夸大了实际数据的外观和不规则性。

由于源数据本身很长,经常更新,而不是由开发人员维护;它很容易错过关键字段或手动输入的重复值。因此,希望完全以编程方式完成它。我不能指望数据所有者正确地做到这一点。他们无法读取代码,所以理想情况下我宁愿不要使用大量的“编程goop”搞乱数据结构。

对集合进行了几次操作,将某些元素的各种运行放入其他动态创建的包装器中,这样最终集合实际上是在最终显示之前由一些转换,过滤器和映射生成的。

1 个答案:

答案 0 :(得分:0)

Wes Bos致敬,他提出了一个有效的聪明解决方案!

代码是一个简单的单行代码,完全符合我的要求:

c = c.map( (el,key) => React.cloneElement(el, {key} ));

我们正在使用 .cloneElement()方法构建一个新集合,这是我不知道的。事实证明,这就是我所需要的。

.map()操作中,lambda函数同时传递元素和索引。它的返回值是克隆元素,但设置了键属性。

通过巧妙地命名索引元素key,它允许表达式{ "key" : key }的简短表示法。该对象扩充了克隆对象。

最后,我最终得到了一个新的相同对象集合,每个对象都有一个设置为索引的键属性。