Rules
no-array-index-key

no-array-index-key

Rule category

Suspicious.

What it does

Warns when an array index is used as a key prop.

Why is this bad?

The order of items in a list rendering can change over time if an item is inserted, deleted, or the array is reordered. Indexes as keys often lead to subtle and confusing errors.

Examples

Failing

import React from "react";
 
interface ExampleProps {
  
ExampleProps.items: {
    id: string;
    name: string;
}[]
items
: { id: stringid: string; name: stringname: string }[];
} function function Example({ items }: ExampleProps): React.JSX.ElementExample({
items: {
    id: string;
    name: string;
}[]
items
}: ExampleProps) {
return ( <JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>ul> {
items: {
    id: string;
    name: string;
}[]
items
.
Array<{ id: string; name: string; }>.map<React.JSX.Element>(callbackfn: (value: {
    id: string;
    name: string;
}, index: number, array: {
    id: string;
    name: string;
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
((
item: {
    id: string;
    name: string;
}
item
, index: numberindex) => (
// - Do not use Array index as key. <JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>li React.Attributes.key?: React.Key | null | undefinedkey={index: numberindex}>{
item: {
    id: string;
    name: string;
}
item
.name: stringname}</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>li>
))} </JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>ul> ); }

Passing

import React from "react";
 
interface ExampleProps {
  
ExampleProps.items: {
    id: string;
    name: string;
}[]
items
: { id: stringid: string; name: stringname: string }[];
} function function Example({ items }: ExampleProps): React.JSX.ElementExample({
items: {
    id: string;
    name: string;
}[]
items
}: ExampleProps) {
return ( <JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>ul> {
items: {
    id: string;
    name: string;
}[]
items
.
Array<{ id: string; name: string; }>.map<React.JSX.Element>(callbackfn: (value: {
    id: string;
    name: string;
}, index: number, array: {
    id: string;
    name: string;
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
((
item: {
    id: string;
    name: string;
}
item
) => (
<JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>li React.Attributes.key?: React.Key | null | undefinedkey={
item: {
    id: string;
    name: string;
}
item
.id: stringid}>{
item: {
    id: string;
    name: string;
}
item
.name: stringname}</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>li>
))} </JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>ul> ); }

Further Reading