Search code examples
reactjskey

How to use an array of elements multiple times in React? (unique keys)


Given an array of colours I have mapped to an array of option elements to fill a select element. Each option has a unique key but I can only use the mapped array once else the keys will no longer be unique. How can I get around this without something over the top?

const colours=[ 
  {name:'red',hex:'ff0000',id:'4855r234'}, 
  {name:'green',hex:'00ff00',id:'1324855g'}, 
  {name:'blue',hex:'0000ff',id:'b324899'} 
] 

const colourOptions=colours.map(colour => 
  <option value={colour.hex} key={colour.id}>{colour.name}</option> 
) 

return ( 
  <form>
    <select name='shirt'>{colourOptions}</select>
    <select name='hat'>{colourOptions}</select> 
  </form> 
) 

This gives an "Encountered two children with the same key" warning as obviously I am repeating the same keys. I could write a function which returns a new map each time with randomised keys but this feels like an ugly solution, I wanted to know what is considered the best approach?

Note:This is a minimal example, I have left out all of the controlled component code for the inputs.


Solution

  • The best way to solve this problem is to return a different id from the parent and the code will look like this:

    const colors=[ 
          {name:'red',hex:'ff0000',id:'4855r234'}, 
          {name:'green',hex:'00ff00',id:'1324855g'}, 
          {name:'blue',hex:'0000ff',id:'b324899'} 
       ] 
       const colorOptions = (color) => {
          return <option value={color.hex} key={color.id}>{color.name}</option>
       };
    
       return (
          <form>
             <select name="shirt">
                {colors.map((color) => colorOptions(color))}
             </select>
             <select name="hat">
                {colors.map((color) => colorOptions(color))}
             </select>
          </form>
       );