من یک کامپوننت React ساختم که منبع داده ای با قالب JSON دریافت می کند و یک جدول که قابلیت مرتب شدن دارد ایجاد می کند.
هر یک از سطرهای داده یک کلید منحصر به فرد دارد اما هنوز خطای:
Each child in an array should have a unique "key" prop.
Check the render method of TableComponent.
را دریافت می کنم.
متد render کامپوننت TableComponent، کد زیر را بر می گرداند:
<table>
<thead key="thead">
<TableHeader columns={columnNames}/>
</thead>
<tbody key="tbody">
{ rows }
</tbody>
</table>
کامپوننت TableHeader یک سطر است و یک کلید منحصر به فرد هم به آن اختصاص داده شده است.
هر row در rows با کامپوننت و کلید منحصر به فرد ایجاد شده است:
<TableRowItem key={item.id} data={item} columns={columnNames}/>
و کامپوننت TableRowItem هم به شکل زیر است:
var TableRowItem = React.createClass({
render: function() {
var td = function() {
return this.props.columns.map(function(c) {
return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
}, this);
}.bind(this);
return (
<tr>{ td(this.props.item) }</tr>
)
}
});
دلیل این خطا چیست؟
شما باید یک کلید برای هر فرزند و همچنین عناصر داخل فرزند مشخص کنید. React از این طریق می تواند تغییرات در DOM را handle کند.
در کد شما هر <TableRowItem key={item.id} data={item} columns={columnNames}/>
سعی می کند تا برخی از فرزندانش را بدون کلید رندر کند.
این مثال را چک کنید.
key={i} را از عنصر <b></b>
که داخل div قرار دارد حذف کنید و console را چک کنید.
در کد نمونه زیر اگر نخواهیم یک کلید به هر عنصر <b>
اختصاص دهیم و فقط بخواهیم object.city
بروزرسانی شود، React مجددا به جای اینکه فقط element را رندر مجدد کند کل سطر را رندر مجدد می کند.
var data = [{name:'Jhon', age:28, city:'HO'},
{name:'Onhj', age:82, city:'HN'},
{name:'Nohj', age:41, city:'IT'}
];
var Hello = React.createClass({
render: function() {
var _data = this.props.info;
console.log(_data);
return(
<div>
{_data.map(function(object, i){
return <div className={"row"} key={i}>
{[ object.name ,
// remove the key
<b className="fosfo" key={i}> {object.city} </b> ,
object.age
]}
</div>;
})}
</div>
);
}
});
React.render(<Hello info={data} />, document.body);