facebook/react · warning

Using Maps as children is not supported. Use an array of key

Error message

Using Maps as children is not supported. Use an array of keyed ReactElements instead.

What it means

ReactChildren's mapIntoArray handles iterable children by using their iterator function; a Map's default iterator is entries(), which yields [key, value] arrays rather than elements, so React would try to render key-value pairs. The dev-only check compares the child's iteratorFn to children.entries and warns once, directing you to pass an array of keyed ReactElements (ReactChildren.js:296).

Source

Thrown at packages/react/src/ReactChildren.js:296

        child,
        array,
        escapedPrefix,
        nextName,
        callback,
      );
    }
  } else {
    const iteratorFn = getIteratorFn(children);
    if (typeof iteratorFn === 'function') {
      const iterableChildren: Iterable<React$Node> & {
        entries: any,
      } = children as any;

      if (__DEV__) {
        // Warn about using Maps as children
        if (iteratorFn === iterableChildren.entries) {
          if (!didWarnAboutMaps) {
            console.warn(
              'Using Maps as children is not supported. ' +
                'Use an array of keyed ReactElements instead.',
            );
          }
          didWarnAboutMaps = true;
        }
      }

      const iterator = iteratorFn.call(iterableChildren);
      let step;
      let ii = 0;
      // $FlowFixMe[incompatible-use] `iteratorFn` might return null according to typing.
      while (!(step = iterator.next()).done) {
        child = step.value;
        nextName = nextNamePrefix + getElementKey(child, ii++);
        subtreeCount += mapIntoArray(
          child,
          array,

View on GitHub (pinned to eafeac097b)

Solutions

  1. Convert to keyed elements: Array.from(map.entries()).map(([id, item]) => <Item key={id} item={item} />)
  2. If only values matter: [...map.values()] with a key derived from each value
  3. Normalize at the component boundary with the isMap guard below so any iterable input is rendered deterministically

Example fix

// before
<div>{itemsMap}</div>

// after
<div>{Array.from(itemsMap, ([id, item]) => <Item key={id} item={item} />)}</div>
Defensive patterns

Strategy: type-guard

Validate before calling

// normalize any child input before rendering
const isMap = (x) => typeof Map === 'function' && x instanceof Map;
function normalizeChildren(children) {
  if (isMap(children)) {
    return Array.from(children, ([key, node]) => (
      <Fragment key={String(key)}>{node}</Fragment>
    ));
  }
  return children;
}

Type guard

const isMap = (x) => typeof Map === 'function' && x instanceof Map;

Prevention

When it happens

Trigger: Rendering a Map directly as children: <ul>{itemsMap}</ul> where itemsMap is a Map instance; or a wrapper component forwarding an arbitrary iterable that happens to be a Map.

Common situations: Switching keyed collections from plain objects to Map for key ordering/guaranteed string keys (i18n tables, id-to-node registries, caches) and passing them straight into JSX.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/3296d523ee85f17e. Report an issue: GitHub.