Diagnostics

LUM2006: Reactive index escapes its callback

The reactive index of a .map() row is used outside its row.

Severity: warning · Category: reactivity (2xxx)

Reported by: the compiler. A warning.

#What it means

In {items().map((item, i) => …)} the compiler makes i a reactive index that belongs to the row and updates when the row moves. Storing it in an outer variable, or capturing it in a callback that outlives the row, keeps a stale index.

#Example

tsx
let lastIndex = 0;
export function List(props: { items: string[] }) {
  return (
    <ul>
      {props.items.map((item, i) => {
        lastIndex = i;
        return <li>{item}</li>;
      })}
    </ul>
  );
}

#How to fix it

Use the index only inside the row's JSX and handlers. To remember a position, store the item (or its key) and look it up when needed.

Not reported when the list maps a module-level const array literal (also with as const) that the module never changes: no reassignment, no X[i] = …, no push, sort, splice or other mutating method. Its rows never move, so reading the index once is safe:

tsx
const CHANNELS = [{ name: "pulse" }, { name: "wave" }] as const;
export function Mixer() {
  return (
    <ul>
      {CHANNELS.map((info, i) => {
        const ch = i; // stable: CHANNELS never changes
        return (
          <li>
            {info.name} {ch}
          </li>
        );
      })}
    </ul>
  );
}