== Why is this an issue?

To optimize the rendering of React list components, a unique identifier (UID) is required in the `key` attribute for each list item. This UID lets React identify the item throughout its lifetime.  Using generated values like `Math.random()` or `Date.now()` is discouraged as their return value will differ between calls, causing the keys to not match up between renders, recreating the DOM. Also, this may cause bugs if values collide.

[source,javascript,diff-id=1,diff-type=noncompliant]
----
function Blog(props) {
  return (
    <ul>
      {props.posts.map((post) =>
        <li key={Math.random()}> <!-- Noncompliant: Since the 'key' will be different on each render, React will update the DOM unnecessarily -->
          {post.title}
        </li>
      )}
    </ul>
  );
}
----

To fix it, use a string or a number that uniquely identifies the list item. The key must be unique among its siblings, not globally.

If the data comes from a database, database IDs are already unique and are the best option. Otherwise, use a counter or a UUID generator.

Avoid using array indexes since, even if they are unique, the order of the elements may change. 


[source,javascript,diff-id=1,diff-type=compliant]
----
function Blog(props) {
  return (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
}
----

== Resources

=== Documentation

* https://react.dev/learn/rendering-lists#rules-of-keys[React API reference - Rendering lists]
* https://reactjs.org/docs/reconciliation.html#recursing-on-children[React API reference - Recursing On Children]
* https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID[MDN - Crypto: randomUUID() method]
* https://en.wikipedia.org/wiki/Universally_unique_identifier[Wikipedia - UUID]

=== Related rules

* S6477 - JSX list components should have a key property
* S6479 - JSX list components should not use array indexes as key
