react-doctor/preact-no-children-length
Wrap with toChildArray(children) from preact before reading .length or calling array methods on props.children.
- Category: Bugs
- Severity: warn
- Source:
oxlint-plugin-react-doctor - Framework: preact
- Enabled when: framework=preact and capabilities=preact
- Default: Enabled
- Documentation: https://preactjs.com/guide/v10/api-reference/#tochildarray
Validation prompt
Use this to decide whether a fired diagnostic is real or a false positive.
Fires on a non-computed MemberExpression whose property identifier is one of length, map, forEach, filter, find, reduce, some, every, flat, flatMap, indexOf, includes, slice, concat, or join (ARRAY_READ_METHOD_NAMES), AND whose object is the children tail of props.children, this.props.children, or a bare children identifier that destructures from the first param of the enclosing function as ({ children }) — e.g. props.children.length, props.children.map(...), this.props.children.forEach(...), or children.filter(...) inside function Wrapper({ children }). False positive boundary: already-normalized toChildArray(props.children).length or toChildArray(children).map(...); computed access props.children[method] or index access props.children[0]; React.Children.map(props.children, ...); .length on an unrelated prop like items.length; a local const children = fetchChildNodes() that is NOT a destructured prop; and a plain (children) => children.length helper where children is a positional (non-destructured) param of a non-component function — none of these fire.
Fix prompt
Use this once validation confirms the diagnostic is real.
Import toChildArray from preact and wrap the children value before any array access: change props.children.map(fn) to toChildArray(props.children).map(fn), props.children.length to toChildArray(props.children).length, and destructured children.forEach(fn) to toChildArray(children).forEach(fn). In Preact props.children is a single VNode (not an array) when there is exactly one child, so .map/.length/.forEach throw at runtime; toChildArray normalizes it to a flat array for zero, one, or many children. See https://preactjs.com/guide/v10/api-reference/#tochildarray
Related rules
More Bugs rules from the rules reference:
react-doctor/preact-no-react-hooks-import: Import hooks from `preact/hooks` (or `preact/compat`), not `react`: import { useState } from "preact/hooks"react-doctor/preact-no-render-arguments: Drop render's positional params and read this.props / this.state inside render() insteadreact-doctor/preact-prefer-ondblclick: Rename onDoubleClick to onDblClick on host elements: <li onDblClick={openInline}> — Preact uses DOM event namesreact-doctor/preact-prefer-oninput: Replace onChange with onInput on text-like inputs: onInput={(e) => setQuery(e.currentTarget.value)}react-doctor/prefer-use-effect-event: Wrap the callback with `useEffectEvent(callback)` (React 19+) and call the resulting binding from inside the sub-handler. The Effect Event captures the latest props/state without being a reactive dep, so the effect doesn't re-subscribe on every parent render. See https://react.dev/reference/react/useEffectEvent