我正在构建一个React组件,它接受JSON数据源并创建一个可排序的表。 每个动态数据行都有一个唯一的键分配给它,但我仍然得到一个错误:

数组中的每个子元素都应该有一个唯一的“key”道具。 检查TableComponent的渲染方法。

我的TableComponent渲染方法返回:

<table>
  <thead key="thead">
    <TableHeader columns={columnNames}/>
  </thead>
  <tbody key="tbody">
    { rows }
  </tbody>
</table>

TableHeader组件是单行,也有一个唯一的键赋给它。

行中的每一行都是由一个具有唯一键的组件构建的:

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

是什么导致唯一键道具错误?


当前回答

如果我们有数组对象数据。然后我们绘制地图来显示数据。并传递唯一的id (key = {product。Id})因为浏览器可以选择唯一的数据。

example : [
    {
        "id": "1",
        "name": "walton glass door",
        "suplier": "walton group",
        "price": "50000",
        "quantity": "25",
        "description":"Walton Refrigerator is the Best Refrigerator brand in bv 
         Bangladesh "
    },
    {
        
        "id": "2",
        "name": "walton glass door",
        "suplier": "walton group",
        "price": "40000",
        "quantity": "5",
        "description":"Walton Refrigerator is the Best Refrigerator brand in 
         Bangladesh "
    },
}

现在我们映射数据并传递唯一id:

{
    products.map(product => <product product={product} key={product.id} 
    </product>)
}

其他回答

在ReactJS中,如果你要渲染一个元素数组,那么每个元素都应该有一个唯一的键。通常这种情况会产生一个列表。

例子:

function List() {
  const numbers = [0,1,2,3];
 
  return (
    <ul>{numbers.map((n) => <li> {n} </li>)}</ul>
  );
}

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

在上面的例子中,它使用li标签创建了一个动态列表,所以由于li标签没有唯一键,所以它显示了一个错误。

固定后:

function List() {
  const numbers = [0,1,2,3];
 
  return (
    <ul>{numbers.map((n) => <li key={n}> {n} </li>)}</ul>
  );
}

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

当你没有唯一键时使用map的替代解决方案(react eslint不推荐这样做):

function List() {
  const numbers = [0,1,2,3,4,4];
 
  return (
    <ul>{numbers.map((n,i) => <li key={i}> {n} </li>)}</ul>
  );
}

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

实例:https://codepen.io/spmsupun/pen/wvWdGwG

当你对呈现的项目没有稳定的id时,你可以使用项目索引作为关键字作为最后的手段:

const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
   <li key={index}>
      {todo.text}
   </li>
);

请参考列表和键-反应

我不做详细的解释,但这个答案的关键是“关键” 只需将key属性放在标签中,并确保每次迭代时都赋予它唯一的值

#确保键的值不与其他值冲突

例子

<div>
        {conversation.map(item => (
          <div key={item.id  } id={item.id}>
          </div>
        ))}
      </div>

conversation是一个数组,如下所示:

  const conversation = [{id:"unique"+0,label:"OPEN"},{id:"unique"+1,label:"RESOLVED"},{id:"unique"+2,label:"ARCHIVED"},
   ]

您应该为每个子元素以及子元素中的每个元素添加一个键。

这样React就可以处理最小的DOM更改。

在代码中,每个<TableRowItem key={项。id} data={item} columns={columnNames}/>试图在其中呈现一些没有键的子元素。

请看这个例子。

尝试从div的<b></b>元素中删除key={i}(并检查控制台)。

在本例中,如果我们没有给<b>元素一个键,并且我们只想更新对象。在city中,React需要重新渲染整个行,而不仅仅是元素。

代码如下:

const data = [
  { name: "Nuri", age: 28, city: "HO" },
  { name: "Talib", age: 82, city: "HN" },
  { name: "Jenny", age: 41, city: "IT" },
];

const ExampleComponent = React.createClass({
  render: function () {
    const infoData = this.props.info;
    return (
      <div>
        {infoData.map((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(<ExampleComponent info={data} />, document.body);

下面由@Chris发布的答案比这个答案更详细。

React文档中关于按键在协调中的重要性:按键

当你创建一个没有特殊key属性的元素列表时,React中会出现“列表中的每个子元素都应该有一个唯一的“key”道具”警告。必须为循环中的每个元素分配键,以便为React中的元素提供稳定的标识。

我们可以将对象的id属性设置为唯一键。

export default function App() {
      const posts = [
{ id: 1, title: "First "},
{ id: 2, title: "Second" },
{ id: 3, title: "Third" }
 ];
 return (
<div>
    <ul>
        {posts.map(value => 
            <li key={value.id}>{value.title}</li>
        )}
    </ul>
</div>
 );}


//simple way

//if u using ant design remove the empty fragment...

//worng ans---> change to following crt ans

export default function App() {
      const posts = [
{ id: 1, title: "First "},
{ id: 2, title: "Second" },
{ id: 3, title: "Third" }
 ];
 {fields.map((field,index)=>{
return(
  <> //empty fragment
   <Row key={index}>
    <Col span={6}>hello</Col>
   </Row>
  </>
)
})}

 //correct ans
//remove the empty fragments after solve this key.prop warning problem
export default function App() {
      const posts = [
{ id: 1, title: "First "},
{ id: 2, title: "Second" },
{ id: 3, title: "Third" }
 ];
 {fields.map((field,index)=>{
return(
  <> //empty fragment
   <Row key={index}>
    <Col span={6}>hello</Col>
   </Row>
  </>
)
})}