Alex
Alex

Reputation: 99

Encountered two children with the same key - index doesn't work

Please help? what wrong here? i add index but still have warning

{options.map((value, index ) => (
      <SelectPicker.Item  key={index} label={value} value={value} />
 ))}

Upvotes: 1

Views: 888

Answers (1)

Tom Bombadil
Tom Bombadil

Reputation: 3975

It's bad practice to use index as keys. You can choose any of the below options to avoid indexes or Math.random() for providing keys to react or react native components.

Option 1

Create static ids yourself of the frontend for a list before using the list to render UI elements.

Create a new array like below:

const optionsWithIds = options.map((item, index) => { ...item, id: index });

Then, use it like so:

{optionsWithIds.map((item, index ) => (
      <SelectPicker.Item  key={item.id} label={item.value} value={item.value} />
 ))}

Option 2

If your values are unique, which should be the case. Just assign the value as a key. Keys should always be of type string. In case, value is not of type string, you should convert it to string using .toString(), but also add a check to see if the value exists, else you'll receive an error trying to convert null or undefined to type string, the app will crash.

{options.map((value, index ) => (
      <SelectPicker.Item  key={value} label={value} value={value} />
 ))}

Option 3

Create your own Key generator function.

let key = 0 // Make sure this variable is declared globally.

const getKey = () => {
  key += 1
  return key.toString()
}

export default getKey

Usage:

import getKey from './getKey

{options.map((value, index ) => (
      <SelectPicker.Item  key={getKey()} label={value} value={value} />
 ))}

Option 4 Use the below options only if the above ones can't be used for some reason.

Add this npm module called nanoid to your project and use it instead of index to generate a unique random key. But, use nanoid only in cases where you don't have access to a static unique key element. If you have for eg: an id you receive from the backend, always try to use that. Because the id will remain static (the same) even after a re-render, which is the whole point of using keys in the first place.

Usage:

import { nanoid } from 'nanoid'
// Your other code
<SelectPicker.Item  key={nanoid()} label={value} value={value} />

Option 5

You can also use this npm module called uuid to achieve the same results as option 3.

Usage:

import { v4 as uuidv4 } from 'uuid';

{options.map((value, index ) => (
      <SelectPicker.Item  key={uuidv4()} label={value} value={value} />
 ))}

Hope this helps.

Upvotes: 3

Related Questions