React Rails应用程序中动态子项的密钥分配问题

Issue with key assignment to dynamic children in React-Rails app

本文关键字:密钥 分配 问题 Rails 应用程序 动态 React      更新时间:2023-09-26

我正在Rails上创建一个React应用程序,遇到了一个关于向动态子级分配密钥的问题。

下面是我代码的精简副本:

class Records extends React.Component {
    render () {
        var records = 
            this.props.data.map(function(record) {
                return <div>
                           <Record key={record.id} data={record} />
                        </div>;
            });
        return (
            <div>
                {records}
            </div>
        );
    }
}
class Record extends React.Component {
    render () {
        return (
            <div>
                <h1>Title: {this.props.data.title}</h1>
            </div>
        );
    }
}

除了控制台上出现以下警告外,代码运行正常:

Warning: Each child in an array or iterator should have a unique "key" prop. 
Check the render method of `Records`.

我已经遵循了React指南警告中包含的链接(http://facebook.github.io/react/docs/multiple-components.html#dynamic-儿童)。

尽管我觉得我已经实现了他们的建议,即密钥应该始终直接提供给数组中的组件,而不是提供给数组每个组件的容器HTML子级,但我仍然在控制台中收到了这个警告。

有人知道为什么吗?我非常感谢你能提供的任何帮助!

问题是应该将关键道具添加到外部div,而不是添加到Record实例。

var records = 
            this.props.data.map(function(record) {
                return <div key={record.id}>
                           <Record data={record} />
                        </div>;
            });

事实上,您根本不需要包装div。

之所以出现警告,是因为您需要向重复的元素添加键道具,并且在代码中有一个div列表,每个div都包含一个Record(而不是Records列表)。React要求您这样做,以便能够"跟踪"(识别)这些div,如果没有识别它们的方法,这些div将完全相同。React需要这个id来有效地跟踪DOM突变(例如重新排序、删除等)

然后,如果你使用ES6(用巴别塔或类似的软件传输)和JSX,你可以只使用这个:

var records = this.props.data.map(record => <Record data={record} key={record.id} />)

在您的代码示例中,中的子元素是周围的<div>元素,而不是具有key属性的Record组件。

您得到的HTML结构看起来像这个

<div>
   <div><h1 key="1">...</h1></div>
   <div><h1 key="2">...</h1></div>
   <div><h1 key="3">...</h1></div>
</div>

因此React确实是正确的,集合没有顶级元素的唯一键。

你的两个选择是:

(A) 将key属性添加到周围的<div>,使其看起来像这个

<div>
   <div key="1"><h1>...</h1></div>
   <div key="2"><h1>...</h1></div>
   <div key="3"><h1>...</h1></div>
</div>
var records = 
   this.props.data.map(function(record) { 
      return <div key={record.id}>
                <Record data={record} />
             </div>;

(B) 完全去掉周围的<div>,因为它不需要。

var records = 
    this.props.data.map(function(record) { 
       return <Record key={record.id} data={record} />;

旁注:React希望render调用只返回一个顶级元素,因此如果希望在渲染调用中有多个同级元素,则只需要一个容器元素。