• If you've spent some time with React you've probably seen that familiar error message telling you to provide unique keys. <!-- more --> This error tends to manifest when iterating over an array of elements in jsx.

    Here's what Facebook has to say about the issue:

    Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
    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:
    When you don't have stable IDs for rendered items, you may use the item index as a key as a last resort.

     

    Why Is Using <code>index</code> A Last Resort?

    const groceries = ["eggs", "ham", "cheese"];
    
    const list = groceries.map((groceries, index) => 
        <li key={index}>{groceries}</li>
    );

    This is an antipattern because if you push elements into the array or mutate it the data won't display correctly.

    <code>Math.random()</code> is Even Worse

    Using <code>Math.random()</code> is even worse than using the index for keys.

    <code>Math.random()</code> generates a pseudorandom number between 0 and 1. But it will be different for a given element every time the component mounts which causes a huge performance overhead.

    The Solution

    The solution is to generate static, unique ids for each element.

    • React element keys should be stable; they should not change every time a component mounts or unmounts.
    • React element keys should be unique.

    One quick and dirty method is to use the node package <code>react-key-index</code>. You can install the <a href="">node_module</a> with:

    npm install react-key-index --save

    <code>react-key-index</code> generated a unique id for each element in an array.

    Suppose you have the following array:

    var groceries = ["eggs", "ham", "cheese"];

    You can generate a unique string for each element as follows:

    import keyIndex from 'react-key-index';
    
    var groceries = ["eggs", "ham", "cheese"];
    
    var output = keyIndex(groceries, 1);

    The <code>out</code> array will look something like:

    [ 
      {
        id: "kwH4H0HgH8HZfV",
        value: "eggs"
      }, {
        id: "5lHRH4HgHzfAc9",
        value: "ham"
      }, {
        id: "X7HGHrHLf8cEf3"
        value: "cheese"
      }
    ]

    An astronomical number of these keys can be generated without sacrificing uniqueness.

    You can then use the newly minted IDs in your map function:

    output.map((output) => {
      <li key={output._id}>{output.value}</li>
    }

    What About Objects?

    What if you have an array of objects?

    Suppose you have an array of objects as follows:

    [ 
      { 
        item: "windforce",
        cost: 10000
      }, {
        ...
      }
    ]

    This is necessary when you need to use map() an array of objects and each jsx element needs a unique key.

    Using shortId To Generate Keys

    You can also using shortId to generate keys.

    TL;DR

    • JSX elements need unique, stable keys.
    • Ideally keys should be created when the array is created.
    • Avoid using index or Math.random to generate keys.
    • Use <code>react-key-index</code> or <code>shortId</code> to generate permanent, unique react keys.