简体   繁体   English

了解 React.js 中子数组的唯一键

[英]Understanding unique keys for array children in React.js

I'm building a React component that accepts a JSON data source and creates a sortable table.我正在构建一个接受 JSON 数据源并创建可排序表的 React 组件。
Each of the dynamic data rows has a unique key assigned to it but I'm still getting an error of:每个动态数据行都有一个分配给它的唯一键,但我仍然收到以下错误:

Each child in an array should have a unique "key" prop.数组中的每个孩子都应该有一个独特的“关键”道具。
Check the render method of TableComponent.检查 TableComponent 的 render 方法。

My TableComponent render method returns:我的TableComponent渲染方法返回:

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

The TableHeader component is a single row and also has a unique key assigned to it. TableHeader组件是单行,并且还分配有一个唯一键。

Each row in rows is built from a component with a unique key: rows row从具有唯一键的组件构建的:

<TableRowItem key={item.id} data={item} columns={columnNames}/>

And the TableRowItem looks like this: 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>
    )
  }
});

What is causing the unique key prop error?是什么导致了唯一的密钥道具错误?

You should add a key to each child as well as each element inside children .您应该为每个 child以及 children 中的每个元素添加一个键。

This way React can handle the minimal DOM change.这种方式 React 可以处理最小的 DOM 更改。

In your code, each <TableRowItem key={item.id} data={item} columns={columnNames}/> is trying to render some children inside them without a key.在您的代码中,每个<TableRowItem key={item.id} data={item} columns={columnNames}/>都试图在没有键的情况下在其中呈现一些子项。

Check this example .检查这个例子

Try removing the key={i} from the <b></b> element inside the div's (and check the console).尝试从 div 内的<b></b>元素中删除key={i} (并检查控制台)。

In the sample, if we don't give a key to the <b> element and we want to update only the object.city , React needs to re-render the whole row vs just the element.在示例中,如果我们没有为<b>元素提供键并且我们只想更新object.city ,那么 React 需要重新渲染整行而不是元素。

Here is the code:这是代码:

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

The answer posted by @Chris at the bottom goes into much more detail than this answer. @Chris 在底部发布的答案比这个答案更详细。

React documentation on the importance of keys in reconciliation: Keys React 文档中关于键在对账中的重要性: Keys

Be careful when iterating over arrays!!遍历数组时要小心!

It is a common misconception that using the index of the element in the array is an acceptable way of suppressing the error you are probably familiar with:一个常见的误解是,使用数组中元素的索引是抑制您可能熟悉的错误的可接受方式:

Each child in an array should have a unique "key" prop.

However, in many cases it is not!但是,在很多情况下并非如此! This is anti-pattern that can in some situations lead to unwanted behavior .这是反模式,在某些情况下会导致不需要的行为


Understanding the key prop了解key道具

React uses the key prop to understand the component-to-DOM Element relation, which is then used for the reconciliation process . React 使用key prop 来理解组件与 DOM 元素的关系,然后将其用于协调过程 It is therefore very important that the key always remains unique , otherwise there is a good chance React will mix up the elements and mutate the incorrect one.因此,密钥始终保持唯一非常重要,否则 React 很有可能会混淆元素并改变不正确的元素。 It is also important that these keys remain static throughout all re-renders in order to maintain best performance.为了保持最佳性能,这些键在所有重新渲染过程中保持静态也很重要。

That being said, one does not always need to apply the above, provided it is known that the array is completely static.话虽如此,只要知道数组是完全静态的,并不总是需要应用上述内容。 However, applying best practices is encouraged whenever possible.但是,我们鼓励尽可能采用最佳实践。

A React developer said in this GitHub issue :一位 React 开发人员在这个 GitHub 问题中说:

  • key is not really about performance, it's more about identity (which in turn leads to better performance).关键不是真正的性能,它更多的是关于身份(这反过来会带来更好的性能)。 randomly assigned and changing values are not identity随机分配和变化的值不是身份
  • We can't realistically provide keys [automatically] without knowing how your data is modeled.在不知道您的数据是如何建模的情况下,我们实际上无法 [自动] 提供密钥。 I would suggest maybe using some sort of hashing function if you don't have ids如果您没有 ID,我建议您使用某种散列函数
  • We already have internal keys when we use arrays, but they are the index in the array.我们在使用数组时已经有了内部键,但它们是数组中的索引。 When you insert a new element, those keys are wrong.当您插入一个新元素时,这些键是错误的。

In short, a key should be:简而言之,一个key应该是:

  • Unique - A key cannot be identical to that of a sibling component .唯一- 一个键不能与同级组件的键相同。
  • Static - A key should not ever change between renders.静态- 一个键不应该在渲染之间改变。

Using the key prop使用key道具

As per the explanation above, carefully study the following samples and try to implement, when possible, the recommended approach.根据上面的解释,仔细研究以下示例,并在可能的情况下尝试实施推荐的方法。


Bad (Potentially)不好(可能)

<tbody>
    {rows.map((row, i) => {
        return <ObjectRow key={i} />;
    })}
</tbody>

This is arguably the most common mistake seen when iterating over an array in React.这可以说是在 React 中迭代数组时最常见的错误。 This approach isn't technically "wrong" , it's just... "dangerous" if you don't know what you are doing.这种方法在技术上并不是“错误的” ,它只是...... “危险” ,如果你不知道自己在做什么。 If you are iterating through a static array then this is a perfectly valid approach (eg an array of links in your navigation menu).如果您正在遍历静态数组,那么这是一种完全有效的方法(例如,导航菜单中的链接数组)。 However, if you are adding, removing, reordering or filtering items, then you need to be careful.但是,如果您要添加、删除、重新排序或过滤项目,则需要小心。 Take a look at this detailed explanation in the official documentation.看看官方文档中的这个详细解释

 class MyApp extends React.Component { constructor() { super(); this.state = { arr: ["Item 1"] } } click = () => { this.setState({ arr: ['Item ' + (this.state.arr.length+1)].concat(this.state.arr), }); } render() { return( <div> <button onClick={this.click}>Add</button> <ul> {this.state.arr.map( (item, i) => <Item key={i} text={"Item " + i}>{item + " "}</Item> )} </ul> </div> ); } } const Item = (props) => { return ( <li> <label>{props.children}</label> <input value={props.text} /> </li> ); } ReactDOM.render(<MyApp />, document.getElementById("app"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div>

In this snippet we are using a non-static array and we are not restricting ourselves to using it as a stack.在这个片段中,我们使用了一个非静态数组,并且我们并不限制自己将它用作堆栈。 This is an unsafe approach (you'll see why).这是一种不安全的方法(你会明白为什么)。 Note how as we add items to the beginning of the array (basically unshift), the value for each <input> remains in place.请注意,当我们将项目添加到数组的开头(基本上是不移位)时,每个<input>的值保持不变。 Why?为什么? Because the key doesn't uniquely identify each item.因为key不能唯一标识每个项目。

In other words, at first Item 1 has key={0} .换句话说,首先Item 1key={0} When we add the second item, the top item becomes Item 2 , followed by Item 1 as the second item.当我们添加第二个项目时,最上面的项目变成了Item 2 ,然后是Item 1作为第二个项目。 However, now Item 1 has key={1} and not key={0} anymore.但是,现在Item 1key={1}而不是key={0}了。 Instead, Item 2 now has key={0} !!相反, Item 2现在有key={0} !!

As such, React thinks the <input> elements have not changed, because the Item with key 0 is always at the top!因此,React 认为<input>元素没有改变,因为键为0Item总是在顶部!

So why is this approach only sometimes bad?那么为什么这种方法只是有时不好呢?

This approach is only risky if the array is somehow filtered, rearranged, or items are added/removed.这种方法只有在以某种方式过滤、重新排列或添加/删除项目时才有风险。 If it is always static, then it's perfectly safe to use.如果它始终是静态的,那么使用它是完全安全的。 For example, a navigation menu like ["Home", "Products", "Contact us"] can safely be iterated through with this method because you'll probably never add new links or rearrange them.例如,像["Home", "Products", "Contact us"]这样的导航菜单可以安全地使用此方法进行迭代,因为您可能永远不会添加新链接或重新排列它们。

In short, here's when you can safely use the index as key :简而言之,这是您可以安全地将索引用作key的时候:

  • The array is static and will never change.数组是静态的,永远不会改变。
  • The array is never filtered (display a subset of the array).数组永远不会被过滤(显示数组的子集)。
  • The array is never reordered.数组永远不会重新排序。
  • The array is used as a stack or LIFO (last in, first out).该数组用作堆栈或 LIFO(后进先出)。 In other words, adding can only be done at the end of the array (ie push), and only the last item can ever be removed (ie pop).换句话说,添加只能在数组的末尾进行(即push),并且只能删除最后一项(即pop)。

Had we instead, in the snippet above, pushed the added item to the end of the array, the order for each existing item would always be correct.如果我们相反,在上面的代码片段中,将添加的项目到数组的末尾,每个现有项目的顺序总是正确的。


Very bad很坏

<tbody>
    {rows.map((row) => {
        return <ObjectRow key={Math.random()} />;
    })}
</tbody>

While this approach will probably guarantee uniqueness of the keys, it will always force react to re-render each item in the list, even when this is not required.虽然这种方法可能会保证键的唯一性,但它总是会强制 react 重新渲染列表中的每个项目,即使这不是必需的。 This a very bad solution as it greatly impacts performance.这是一个非常糟糕的解决方案,因为它极大地影响了性能。 Not to mention that one cannot exclude the possibility of a key collision in the event that Math.random() produces the same number twice.更不用说,如果Math.random()两次产生相同的数字,则不能排除密钥冲突的可能性。

Unstable keys (like those produced by Math.random() ) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.不稳定的键(如Math.random()产生的键)会导致许多组件实例和 DOM 节点不必要地重新创建,这可能会导致性能下降和子组件中的状态丢失。


Very good很好

<tbody>
    {rows.map((row) => {
        return <ObjectRow key={row.uniqueId} />;
    })}
</tbody>

This is arguably the best approach because it uses a property that is unique for each item in the dataset.这可以说是 最好的方法,因为它使用的属性对于数据集中的每个项目都是唯一的。 For example, if rows contains data fetched from a database, one could use the table's Primary Key ( which typically is an auto-incrementing number ).例如,如果rows包含从数据库中获取的数据,则可以使用表的主键(通常是一个自动递增的数字)。

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.选择键的最佳方法是使用一个字符串,该字符串在其兄弟项中唯一标识一个列表项。 Most often you would use IDs from your data as keys大多数情况下,您会使用数据中的 ID 作为键


Good好的

componentWillMount() {
  let rows = this.props.rows.map(item => { 
    return {uid: SomeLibrary.generateUniqueID(), value: item};
  });
}

...

<tbody>
    {rows.map((row) => {
        return <ObjectRow key={row.uid} />;
    })}
</tbody>

This is also a good approach.这也是一个很好的方法。 If your dataset does not contain any data that guarantees uniqueness ( eg an array of arbitrary numbers ), there is a chance of a key collision.如果您的数据集不包含任何保证唯一性的数据(例如,任意数字的数组),则可能会发生密钥冲突。 In such cases, it is best to manually generate a unique identifier for each item in the dataset before iterating over it.在这种情况下,最好在迭代之前为数据集中的每个项目手动生成一个唯一标识符。 Preferably when mounting the component or when the dataset is received ( eg from props or from an async API call ), in order to do this only once , and not each time the component re-renders.最好在安装组件或接收数据集时(例如从props或异步 API 调用),以便仅执行一次,而不是每次重新渲染组件时。 There are already a handful of libraries out there that can provide you such keys.已经有一些库可以为您提供这样的密钥。 Here is one example: react-key-index .这是一个示例: react-key-index

This may or not help someone, but it might be a quick reference.这可能会或不会帮助某人,但它可能是一个快速参考。 This is also similar to all the answers presented above.这也类似于上面提供的所有答案。

I have a lot of locations that generate list using the structure below:我有很多使用以下结构生成列表的位置:

return (
    {myList.map(item => (
       <>
          <div class="some class"> 
             {item.someProperty} 
              ....
          </div>
       </>
     )}
 )
         

After a little trial and error (and some frustrations), adding a key property to the outermost block resolved it.经过一些试验和错误(以及一些挫折),在最外面的块中添加一个关键属性解决了它。 Also, note that the <> tag is now replaced with the <div> tag now.另外,请注意<>标记现在已替换为<div>标记。

return (
  
    {myList.map((item, index) => (
       <div key={index}>
          <div class="some class"> 
             {item.someProperty} 
              ....
          </div>
       </div>
     )}
 )

Of course, I've been naively using the iterating index (index) to populate the key value in the above example.当然,在上面的例子中,我一直天真地使用迭代索引(index)来填充键值。 Ideally, you'd use something which is unique to the list item.理想情况下,您会使用列表项独有的东西。

Check: key = undef !!!检查:key = undef !!!

You got also the warn message:您还收到警告消息:

Each child in a list should have a unique "key" prop.

if your code is complete right, but if on如果您的代码完整正确,但如果打开

<ObjectRow key={someValue} />

someValue is undefined!!! someValue 未定义!!! Please check this first.请先检查一下。 You can save hours.您可以节省数小时。

Just add the unique key to the your Components只需将唯一键添加到您的组件

data.map((marker)=>{
    return(
        <YourComponents 
            key={data.id}     // <----- unique key
        />
    );
})

You should use a unique value for each children key of tbody where您应该为tbody的每个子键使用唯一值,其中

  • the value cannot not be identical (same) to its sibling该值不能与其兄弟相同(相同)
  • should not change between renders不应该在渲染之间改变

For example, the key value can be database id or UUID (Universal Unique Identifier) .例如,键值可以是数据库 idUUID(通用唯一标识符)

Here the keys are handling manually:这里的键是手动处理的:

<tbody>
  {rows.map((row) => <ObjectRow key={row.uuid} />)}
</tbody>

You can also let React handle the keys using React.Children.toArray你也可以让 React 使用React.Children.toArray处理键

<tbody>
  {React.Children.toArray(rows.map((row) => <ObjectRow />))}
</tbody>

Warning: Each child in an array or iterator should have a unique "key" prop.警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。

This is a warning as for array items which we are going to iterate over will need a unique resemblance.这是一个警告,因为我们要迭代的数组项需要独特的相似性。

React handles iterating component rendering as arrays. React 将迭代组件渲染处理为数组。

Better way to resolve this is provide index on the array items you are going to iterate over.for example:解决此问题的更好方法是为要迭代的数组项提供索引。例如:

class UsersState extends Component
    {
        state = {
            users: [
                {name:"shashank", age:20},
                {name:"vardan", age:30},
                {name:"somya", age:40}
            ]
        }
    render()
        {
            return(
                    <div>
                        {
                            this.state.users.map((user, index)=>{
                                return <UserState key={index} age={user.age}>{user.name}</UserState>
                            })
                        }
                    </div>
                )
        }

index is React built-in props. index 是 React 内置的道具。

When you don't have stable IDs for rendered items, you may use the item index as a key as a last resort:当您没有渲染项目的稳定 ID 时,您可以使用项目索引作为键作为最后的手段:

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

Please refer to List and Keys - React请参考List and Keys - React

In ReactJS if you are rendering an array of elements you should have a unique key for each those elements.在 ReactJS 中,如果你正在渲染一个元素数组,你应该为每个元素拥有一个唯一的键。 Normally those kinda situations are creating a list.通常这些情况正在创建一个列表。

Example:例子:

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

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

In the above example, it creates a dynamic list using li tag, so since li tag does not have a unique key it shows an error.在上面的示例中,它使用li标签创建了一个动态列表,因此由于li标签没有唯一键,因此会显示错误。

After fixed:固定后:

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

Alternative solution when use map when you don't have a unique key (this is not recommended by react eslint ):当您没有唯一键时使用 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')
);

Live example: https://codepen.io/spmsupun/pen/wvWdGwG现场示例: https ://codepen.io/spmsupun/pen/wvWdGwG

Best solution of define unique key in react: inside the map you initialized the name post then key define by key={post.id} or in my code you see i define the name item then i define key by key={item.id}:在反应中定义唯一键的最佳解决方案:在地图中您初始化名称 post 然后键定义 key={post.id} 或在我的代码中您看到我定义名称项目然后我定义键 key={item.id }:

 <div className="container"> {posts.map(item =>( <div className="card border-primary mb-3" key={item.id}> <div className="card-header">{item.name}</div> <div className="card-body" > <h4 className="card-title">{item.username}</h4> <p className="card-text">{item.email}</p> </div> </div> ))} </div>

我遇到了这个错误消息,因为当需要返回null时,数组中的某些项目会返回<></>

I had a unique key, just had to pass it as a prop like this:我有一个唯一的密钥,只需将它作为这样的道具传递:

<CompName key={msg._id} message={msg} />

This page was helpful:此页面很有帮助:

https://reactjs.org/docs/lists-and-keys.html#keys https://reactjs.org/docs/lists-and-keys.html#keys

In my case, set id to tag就我而言,将 id 设置为 tag

<tbody key={i}>

The problem is solved.问题已经解决了。

This is a warning, But addressing this will make Reacts rendering much FASTER ,这是一个警告,但解决这个问题将使 Reacts 渲染得更快

This is because React needs to uniquely identify each items in the list.这是因为React需要唯一标识列表中的每个项目。 Lets say if the state of an element of that list changes in Reacts Virtual DOM then React needs to figure out which element got changed and where in the DOM it needs to change so that browser DOM will be in sync with the Reacts Virtual DOM.假设如果该列表中某个元素的状态在 Reacts Virtual DOM中发生了变化,那么 React 需要确定哪个元素发生了变化以及它需要在 DOM 中的哪个位置进行更改,以便浏览器 DOM 与 Reacts Virtual DOM 同步。

As a solution just introduce a key attribute to each li tag.作为一种解决方案,只需为每个li标签引入一个key属性。 This key should be a unique value to each element.key应该是每个元素的唯一值。

var TableRowItem = React.createClass({
  render: function() {

    var td = function() {
        return this.props.columns.map(function(c, i) {
          return <td key={i}>{this.props.data[c]}</td>;
        }, this);
      }.bind(this);

    return (
      <tr>{ td(this.props.item) }</tr>
    )
  }
});

This will sove the problem.这将解决问题。

If you are getting error like :

> index.js:1 Warning: Each child in a list should have a unique "key" prop.

Check the render method of `Home`. See https://reactjs.org/link/warning-keys for more information.

Then Use inside map function like:

  {classes.map((user, index) => (
              <Card  **key={user.id}**></Card>
  ))}`enter code here`

This is a simple example,I have used a react condition with && first then map, in the I have added the key the user id to be sure that it's unique这是一个简单的例子,我首先使用了&&的反应条件,然后是映射,在我添加了用户 ID 的key以确保它是唯一的

 <tbody>
                                    {users &&
                                    users.map((user) => {
                                        return <tr key={user._id}>
                                            <td>{user.username}</td>
                                            <td><input
                                                name="isGoing"
                                                type="checkbox"
                                                checked={user.isEnabled}
                                                onChange={handleInputChangeNew}/></td>
                                            <td>{user.role.roleTitle} - {user.role.department.departmentName}</td>
                                            {/*<td className="text-right">
                                                    <Button>
                                                        ACTION
                                                    </Button>
                                                </td>*/}
                                        </tr>
                                    })
                                    }


                                    </tbody>
if we have array object data . then we are map for showing  the data . and pass the unique id (key = {product.id} ) because browser can selected the unique data 

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 "
    },
}


now we are maping the data and pass the unique id: 
{
    products.map(product => <product product={product} key={product.id} 
    </product>)
}

Here are the React docs that explain well using the Key property, the key should be defined at the parent component it should not be used inside the child component.这是使用 Key 属性很好地解释的 React 文档,键应该在父组件中定义,它不应该在子组件中使用。 React Docs 反应文档

在此处输入图像描述

在此处输入图像描述

Due to React docs , each row/item should have a unique key.由于React 文档,每一行/项目都应该有一个唯一的键。

Keys help React identify which items have changed, are added, or are removed.键帮助 React 识别哪些项目已更改、添加或删除。

Personally, I prefer using the crypto interface to generate a random UUID:就个人而言,我更喜欢使用加密接口来生成随机 UUID:
( crypto is built-in in vanilla-js) crypto内置在 vanilla-js 中)

const numbers = [1, 2, 3, 4, 5];

const listItems = numbers.map((number) =>
  <li key={crypto.randomUUID()}>item {number}
  </li>
);

Create a random UUID using uuid lib:使用 uuid 库创建一个随机 UUID:
run npm install uuid运行npm install uuid

import { v4 as uuid } from "uuid";

array.map((item) =>
  <li key={uuid()}>{item}
  </li>
);

I don't go with the detail explanation but key to this answer is "key" just put the key attribute in your tag and ensure that every-time you iterate you give unique value to it我没有详细解释,但这个答案的关键是“关键”,只需将关键属性放在您的标签中,并确保每次迭代时都赋予它独特的价值

#ensure that key's value is not clashing with others #确保键的值不会与其他值冲突

Example例子

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

where conversation is an array something like below :其中对话是一个数组,如下所示:

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

your key should be unique.like an unique id.And your code should be like this你的密钥应该是唯一的。就像一个唯一的 id。你的代码应该是这样的

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

A visual explanation.视觉解释。

  1. The incorrect way key=index (of an array)不正确的方式 key=index (数组)

在此处输入图像描述

As you can see, label 3, label 2, and label 1 ALL got re-rendered (flashing in the Elements panel).如您所见,label 3、label 2 和 label 1全部重新渲染(在元素面板中闪烁)。

  1. The correct way key=uniqueId正确的方式key=uniqueId 在此处输入图像描述

Only the top new element flashes (gets re-rendered).只有顶部的新元素会闪烁(重新渲染)。

I think when working with tables (or in similar examples), creating a unique key should be passed to child component from the parent component for the sake of REUSABILITY.我认为在使用表(或类似示例)时,为了可重用性,创建一个唯一键应该从父组件传递给子组件。

Because if you are creating a table, that means you are passing data from the parent.因为如果你正在创建一个表,那意味着你正在从父级传递数据。 If you assign key={row.name} maybe currently data has name property but if you want to use this table component somewhere else you assume that in each row of data that you have passed, you have name property.如果您分配key={row.name}可能当前数据具有name属性,但如果您想在其他地方使用此表组件,您假设在您传递的每一行数据中,您都具有name属性。

Since the engineer will be preparing the data in the parent component, the engineer should create a key function based on the data.由于工程师将在父组件中准备数据,因此工程师应根据数据创建密钥 function。

const keyFunc = (student) => {
    return student.id;
  }; 

In this case engineer knows what data it is sending, it knows that each row has id property which is unique.在这种情况下,工程师知道它正在发送什么数据,它知道每一行都有唯一的 id 属性。 Maybe in the different data set, the data set is stock prices and it does not have "id" property but "symbol"也许在不同的数据集中,数据集是股票价格,它没有“id”属性,而是“symbol”

 const keyFunc = (stock) => {
        return stock.symbol;
      }; 

this keyFunc should be passed to the child component as a prop这个keyFunc应该作为 prop 传递给子组件

The "Each child in a list should have a unique "key" prop." “列表中的每个孩子都应该有一个独特的‘关键’道具。” warning happens in React when you create a list of elements without the special key attribute.当您创建没有特殊 key 属性的元素列表时,React 中会出现警告。 Keys must be assigned to each element in a loop to give stable identity to elements in React.必须将键分配给循环中的每个元素,以便为 React 中的元素提供稳定的标识。

We can set the id property of the object as a unique key.我们可以将 object 的 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>
  </>
)
})}

I faced a similar problem but not exact.我遇到了类似的问题,但不准确。 Tried every possible solution and couldn't get rid of that error尝试了所有可能的解决方案,但无法摆脱该错误

Each child in an array should have a unique "key" prop.数组中的每个孩子都应该有一个唯一的“关键”道具。

Then I tried opening it in a different local host.然后我尝试在不同的本地主机中打开它。 I don't know how, but it worked!我不知道如何,但它有效!

If you are struggling with this error Each child in a list should have a unique "key" prop.如果您正在为这个错误而苦苦挣扎,列表中的每个孩子都应该有一个唯一的“关键”道具。

Solve by declaring index value to the key attribute inside the rendering element.通过将索引值声明给呈现元素内的键属性来解决。

App.js component App.js 组件

import Map1 from './Map1';

const arr = [1,2,3,4,5];

const App = () => {
  return (
    <>
     
     <Map1 numb={arr} />     

    </>
  )
}

export default App

Map.js component Map.js 组件

const Map1 = (props) => {

    let itemTwo = props.numb;
    let itemlist = itemTwo.map((item,index) => <li key={index}>{item}</li>)

    return (
        <>        
        <ul>
            <li style={liStyle}>{itemlist}</li>
        </ul>
        </>
    )
}

export default Map1

I fixed this using Guid for each key like this: Generating Guid:我为每个键使用 Guid 修复了这个问题:生成 Guid:

guid() {
    return this.s4() + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' +
        this.s4() + '-' + this.s4() + this.s4() + this.s4();
}

s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
}

And then assigning this value to markers:然后将此值分配给标记:

{this.state.markers.map(marker => (
              <MapView.Marker
                  key={this.guid()}
                  coordinate={marker.coordinates}
                  title={marker.title}
              />
          ))}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM