最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React list with no keys - Stack Overflow

programmeradmin3浏览0评论

I have an array of number that I wish to render in a tabular form. The array is returned from an API call, not generated by my app.

The data may change but is unlikely to do so, and in any case there are only twenty odd values, so re-rendering the whole table is not really a problem.

A simple data.map(value => <td>{value}</td> should do it.

But I keep getting an Each child in an array or iterator should have a unique "key" prop. warning. Is there any way that I can tell React that there is no key and that I wish it to re-render the whole table if anything changes.

Alternatively, is there any way that I can generate a unique key for each entry? The data items are not guaranteed to be unique.

I should add that I understand what keys are for and why they are useful, but in this instance I do not have any and the easiest thing would be not to use them, since there is unlikely to be a re-render.

I have an array of number that I wish to render in a tabular form. The array is returned from an API call, not generated by my app.

The data may change but is unlikely to do so, and in any case there are only twenty odd values, so re-rendering the whole table is not really a problem.

A simple data.map(value => <td>{value}</td> should do it.

But I keep getting an Each child in an array or iterator should have a unique "key" prop. warning. Is there any way that I can tell React that there is no key and that I wish it to re-render the whole table if anything changes.

Alternatively, is there any way that I can generate a unique key for each entry? The data items are not guaranteed to be unique.

I should add that I understand what keys are for and why they are useful, but in this instance I do not have any and the easiest thing would be not to use them, since there is unlikely to be a re-render.

Share Improve this question edited Jun 2, 2021 at 14:01 Alfonso Tienda 3,6891 gold badge22 silver badges36 bronze badges asked Jan 10, 2018 at 18:07 amayamay 4152 gold badges6 silver badges15 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 10

You can use the index as the key. I think its worth reiterating that using the index as the key only works fine in the very specific scenario that the OP is facing.

This is particularly annoying when requirements change and all of sudden the list is being modified. This shows up as items not being updated during the render because the item updated has the same key (the index), its value is different, but react only cares about the key.

In cases where your data has no unique key. You should use some function that generates a unique id for each item. A simple version of that function just increments a global counter:

// Declared globally (as in attached to window object or equivalent)
var myuniqueidcounter = 0;
function uniqueId() {
    myuniqueidcounter += 1
    return myuniqueidcounter;
}


// Do this in the props change or whereever your data gets passed in
let keyedData = data.map(value => Object.assign(value, { Id: uniqueId() });

// In render
data.map(value => <td key={value.Id}>{value}</td>

That way, on multiple render calls, the ids returned are always unique. We assign the key when we get the data to avoid having to re-render the entire list on each call to render().

However, this case is actually pretty rare as you can usually find some combination of the backing data that will produce a unique key for each entry.

If you do go index-as-key

This article lists 3 conditions that should be met when choosing index-as-key approach that I think is a good check list:

  1. The list and items are static–they are not computed and do not change;

  2. The items in the list have no ids;

  3. The list is never reordered or filtered.

data.map((value,index) =>{ 
  <td key={index}>{value}</td>}
) 

or

  data.map((value,index) =>{ 
       let i = Math.floor(Math.random() * 1000+1)
      <td key={i}>{value}</td>}
   ) 

You can use index as your key as it is unique each time

Based on the question asked, it might be worth saying that there is an another solution to this that doesn't use keys:

e.g. The following will complain about not having unique keys:

React.createElement('div', {}, [<span>1</span>, <span>2</span>]);

However, the following renders all children with no problems (This is what JSX transformed to JS looks like for nodes with multiple children):

React.createElement('div', {}, <span>1</span>, <span>2</span>);

So if you have e.g. a smallish list of generated react element fragments and unique keys don't offer and advantage in your situation, you can do:

React.createElement.apply(null, ['div', {}, ...elementList])

Notes:

  1. elementList is passed as arguments to React.createElement which might be an issue if the list is huge.
  2. It will re-render all the children with each render.
  3. Using unique keys is generally the recommended approach, and is more performant for re-rendering.
  4. However there are occasions where you just want to render in a single shot and don't care about re-rendering, or the data is not structured in a way that you can make good use of unique keys. You can use this as a work-around if you really need to.
发布评论

评论列表(0)

  1. 暂无评论