logoESLint React

no-children-count

Disallows the use of 'Children.count' from the 'react' package.

Full Name in eslint-plugin-react-x

react-x/no-children-count

Full Name in @eslint-react/eslint-plugin

@eslint-react/no-children-count

Presets

x recommended recommended-typescript recommended-type-checked strict strict-typescript strict-type-checked

Rule Details

Using Children.count to inspect the children tree is a form of React child introspection. It creates fragile coupling between parent and child components:

  • Breaks when children are wrapped in HOCs, forwardRef, or memo.
  • Prevents React from optimizing rendering.
  • Creates implicit contracts that types can't enforce.
  • Makes composition unpredictable with fragments, portals, and other React features.

Prefer these alternatives:

  • Compound components with context
  • Render props or slot props
  • Data-driven APIs (array of config objects)
  • CSS-based solutions (grid, flexbox, :nth-child, etc.)

See common alternatives.

Examples

Counting children to conditionally render

Relying on Children.count makes your component tightly coupled to React's internal children representation. Instead, let the parent decide what to render or use standard JavaScript patterns.

For example, if you need to know how many items to display, you can accept an array as a prop directly and use .length:

// 🟢 Recommended: accept data as an array prop
interface MyComponentProps {
  items: string[];
}

function MyComponent({ items }: MyComponentProps) {
  return (
    <>
      <h1>Total rows: {items.length}</h1>
      {items.map((item) => (
        <div key={item}>{item}</div>
      ))}
    </>
  );
}
// 🔴 Problem: Using Children.count to determine the number of children
import React, { Children } from "react";

interface MyComponentProps {
  children: React.ReactNode;
}

function MyComponent({ children }: MyComponentProps) {
  return (
    <>
      <h1>Total rows: {Children.count(children)}</h1>
      ...
    </>
  );
}

Using component composition

Instead of counting children, compose components so that the parent controls the layout and the child components render what they receive.

// 🟢 Recommended: use component composition to wrap items
interface RowListProps {
  children: React.ReactNode;
}

function RowList({ children }: RowListProps) {
  return <div className="RowList">{children}</div>;
}

interface RowProps {
  children: React.ReactNode;
}

function Row({ children }: RowProps) {
  return <div className="Row">{children}</div>;
}

function App() {
  return (
    <RowList>
      <Row><p>First item</p></Row>
      <Row><p>Second item</p></Row>
    </RowList>
  );
}

Conditionally rendering based on item count

If a component needs to show different UI depending on how many items there are, let the parent compute the count from its own data rather than inspecting children.

// 🟢 Recommended: compute the count from props in the parent
interface ItemListProps {
  items: string[];
}

function ItemList({ items }: ItemListProps) {
  const hasItems = items.length > 0;
  return (
    <div>
      {hasItems ? (
        <ul>
          {items.map((item) => (
            <li key={item}>{item}</li>
          ))}
        </ul>
      ) : (
        <p>No items available.</p>
      )}
    </div>
  );
}

Versions

Resources

Further Reading


See Also

On this page