Skip to content
Ilha
Esc
↑↓navigate↵open⌘Jpreview
On this page

ILHA005: Duplicate key among sibling components

Two components in the same parent use the same key.

Keys identify component instances so Ilha keeps their state when a list reorders. A key used twice in one parent is ambiguous, so Ilha warns with ILHA005. The duplicate keeps its state by position instead.

Why it happens

  • You derive keys from a field that is not unique, such as a name or a category.
  • You hard-code the same key on two siblings.

Bad

const Row = ({ label }: { label?: unknown }) => <li>{String(label)}</li>;

const List = () => (
  <ul>
    <Row key="a" label="first" />
    <Row key="a" label="second" />
  </ul>
);

Fixed

Give each sibling a unique key, such as a stable id:

const 
const Row: ({ label }: {
    label?: unknown;
}) => View
Row
= ({ label: unknownlabel }: { label?: unknownlabel?: unknown }) => <JSX.IntrinsicElements.li: LiHTMLAttributesli>{
var String: StringConstructor
(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
String
(label: unknownlabel)}</JSX.IntrinsicElements.li: LiHTMLAttributesli>;
const
const items: {
    id: string;
    label: string;
}[]
items
= [
{ id: stringid: "a", label: stringlabel: "first" }, { id: stringid: "b", label: stringlabel: "second" }, ]; const const List: () => ViewList = () => ( <JSX.IntrinsicElements.ul: HTMLAttributes<HTMLUListElement>ul> {
const items: {
    id: string;
    label: string;
}[]
items
.
Array<{ id: string; label: string; }>.map<View>(callbackfn: (value: {
    id: string;
    label: string;
}, index: number, array: {
    id: string;
    label: string;
}[]) => View, thisArg?: any): View[]
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;
    label: string;
}
item
) => (
<
const Row: ({ label }: {
    label?: unknown;
}) => View
Row
JSX.IntrinsicAttributes.key?: string | number | undefinedkey={
item: {
    id: string;
    label: string;
}
item
.id: stringid} label?: unknownlabel={
item: {
    id: string;
    label: string;
}
item
.label: stringlabel} />
))} </JSX.IntrinsicElements.ul: HTMLAttributes<HTMLUListElement>ul> );

Was this page helpful?