React Child Components

React applications are built by combining components into a hierarchy. When one component renders another component, the rendered component becomes a child component of the component that renders it.

Child components are an important part of React’s component architecture because they allow large interfaces to be divided into smaller, focused, and reusable pieces.

For example:

function Dashboard() {
  return (
    <main>
      <Sidebar />
      <CourseList />
      <ProgressCard />
    </main>
  );
}

Here, Sidebar, CourseList, and ProgressCard are child components of Dashboard.

The structure is:

Dashboard
├── Sidebar
├── CourseList
└── ProgressCard

Each child can have its own JSX, logic, state, events, and responsibilities.

The parent provides the structure and can pass information to its children, while each child handles its own part of the interface.

What Is a Child Component?

A child component is a React component that is rendered by another component.

For example:

function App() {
  return <Header />;
}

Here, Header is a child component of App.

You can visualize it as:

App
└── Header

If Header renders another component:

function Header() {
  return (
    <header>
      <Logo />
      <Navigation />
    </header>
  );
}

Then the hierarchy becomes:

App
└── Header
    ├── Logo
    └── Navigation

Header is a child of App, while Logo and Navigation are children of Header.

A Child Component Can Have Its Own Children

A component isn’t limited to being only a child.

It can also render its own child components.

For example:

function CoursePage() {
  return <CourseSection />;
}

function CourseSection() {
  return (
    <section>
      <CourseList />
      <CourseProgress />
    </section>
  );
}

The hierarchy becomes:

CoursePage
└── CourseSection
    ├── CourseList
    └── CourseProgress

CourseSection is a child of CoursePage, but it is also a parent of CourseList and CourseProgress.

This is how React component trees are built.

Child Components Receive Props

A child component can receive information from its parent through props.

For example:

function CoursePage() {
  return (
    <CourseCard
      title="React Fundamentals"
      progress={75}
    />
  );
}

The child receives those values:

function CourseCard({ title, progress }) {
  return (
    <article>
      <h2>{title}</h2>
      <p>{progress}% complete</p>
    </article>
  );
}

The data flow is:

Parent
  ↓
Props
  ↓
Child

This is the normal direction of data flow in React.

Props Make Child Components Reusable

A child component becomes much more useful when it can receive different data.

For example:

function UserCard({ name, role }) {
  return (
    <article>
      <h2>{name}</h2>
      <p>{role}</p>
    </article>
  );
}

The parent can create multiple child instances:

function Team() {
  return (
    <section>
      <UserCard
        name="Alex"
        role="Frontend Developer"
      />

      <UserCard
        name="Sarah"
        role="UI Designer"
      />

      <UserCard
        name="David"
        role="Backend Developer"
      />
    </section>
  );
}

The hierarchy is:

Team
├── UserCard
├── UserCard
└── UserCard

The same child component is reused with different props.

Child Components and children

React provides a special prop called children.

It contains whatever is placed between a component’s opening and closing tags.

For example:

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

A parent can place another component inside it:

function CoursePage() {
  return (
    <Card>
      <CourseDetails />
    </Card>
  );
}

Here, CourseDetails becomes part of the children passed to Card.

Conceptually:

CoursePage
└── Card
    └── children
        └── CourseDetails

This allows child content to remain flexible.

Child Components Can Contain JSX

A child component is not limited to rendering another component.

It can return normal JSX:

function CourseTitle() {
  return (
    <h2>
      React Fundamentals
    </h2>
  );
}

Or more complex JSX:

function CourseCard() {
  return (
    <article className="course-card">
      <img
        src="/react-course.jpg"
        alt="React course"
      />

      <h2>React Fundamentals</h2>

      <p>
        Learn React from the basics.
      </p>

      <button>
        Start Learning
      </button>
    </article>
  );
}

The parent doesn’t need to know how the card is internally implemented.

It simply renders:

<CourseCard />

Child Components Can Have Their Own State

A child component can manage its own state.

For example:

import { useState } from "react";

function LikeButton() {
  const [liked, setLiked] = useState(false);

  return (
    <button onClick={() => setLiked(!liked)}>
      {liked ? "Liked" : "Like"}
    </button>
  );
}

A parent can render it:

function CourseCard() {
  return (
    <article>
      <h2>React Fundamentals</h2>

      <LikeButton />
    </article>
  );
}

The hierarchy is:

CourseCard
└── LikeButton

LikeButton manages its own liked state.

The parent doesn’t need to manage that state unless another part of the application needs access to it.

Each Child Instance Can Have Independent State

Consider:

function CourseList() {
  return (
    <section>
      <LikeButton />
      <LikeButton />
      <LikeButton />
    </section>
  );
}

Each rendered LikeButton is a separate component instance.

Conceptually:

CourseList
├── LikeButton → liked = true
├── LikeButton → liked = false
└── LikeButton → liked = true

Changing the state of one instance does not automatically change the others.

This is an important property of component-based UI development.

Child Components Can Receive Event Handlers

A parent can pass a function to a child through props.

For example:

function CoursePage() {
  function handleEnroll() {
    console.log("Enrolled");
  }

  return (
    <CourseActions
      onEnroll={handleEnroll}
    />
  );
}

The child receives the callback:

function CourseActions({ onEnroll }) {
  return (
    <button onClick={onEnroll}>
      Enroll Now
    </button>
  );
}

When the user clicks the button, the child calls the function supplied by the parent.

The flow is:

Parent
   ↓
passes callback
   ↓
Child
   ↓
user clicks
   ↓
callback executes

This is one of the standard ways a child can communicate an event to its parent.

Child-to-Parent Communication

React data normally flows from parent to child.

However, a child can communicate information back to its parent by calling a function provided through props.

For example:

function Parent() {
  function handleSelect(value) {
    console.log(value);
  }

  return (
    <Child
      onSelect={handleSelect}
    />
  );
}

The child:

function Child({ onSelect }) {
  return (
    <button onClick={() => onSelect("React")}>
      Select React
    </button>
  );
}

The child isn’t directly changing the parent’s state.

Instead, it calls the callback supplied by the parent.

This is often described as child-to-parent communication, although technically the child is invoking a function that the parent provided.

Child Components Should Have Clear Responsibilities

A good child component usually has a focused responsibility.

For example:

CoursePage
├── CourseHeader
├── CourseDescription
├── LessonList
├── ProgressCard
└── InstructorCard

Each child has a clear purpose.

CourseHeader handles the course heading.

LessonList handles lessons.

ProgressCard handles progress.

InstructorCard handles instructor information.

This makes the parent easier to understand.

Child Components and Reusability

Child components can be reusable.

For example:

function LessonItem({ title, completed }) {
  return (
    <li>
      {title}

      {completed && (
        <span>Completed</span>
      )}
    </li>
  );
}

The parent can use it repeatedly:

function LessonList() {
  return (
    <ul>
      <LessonItem
        title="Introduction to React"
        completed={true}
      />

      <LessonItem
        title="Understanding JSX"
        completed={true}
      />

      <LessonItem
        title="Working with Props"
        completed={false}
      />
    </ul>
  );
}

One child component handles all lesson items.

Child Components in Lists

A parent often renders children from an array.

For example:

const lessons = [
  {
    id: 1,
    title: "Introduction to React"
  },
  {
    id: 2,
    title: "Understanding JSX"
  },
  {
    id: 3,
    title: "Working with Props"
  }
];

Then:

function LessonList() {
  return (
    <ul>
      {lessons.map((lesson) => (
        <LessonItem
          key={lesson.id}
          title={lesson.title}
        />
      ))}
    </ul>
  );
}

Each LessonItem is a child of LessonList.

The key helps React identify individual items in the list.

Child Components and Conditional Rendering

A child component can also be rendered conditionally.

For example:

function Dashboard({ isLoggedIn }) {
  return (
    <main>
      {isLoggedIn && <UserProfile />}
    </main>
  );
}

When isLoggedIn is true, UserProfile is rendered.

When it is false, it isn’t rendered.

The child is therefore controlled by a condition in the parent.

Remember that conditionally hiding an admin interface is not a security mechanism. Authorization and access control must be enforced on the server or backend.

Child Components and Component Boundaries

When deciding whether something should become a child component, consider whether it represents a meaningful part of the interface.

For example, this is reasonable:

CoursePage
├── CourseHeader
├── LessonList
└── InstructorCard

But creating a component for every tiny element can make the application harder to understand:

CoursePage
└── Section
    └── Wrapper
        └── Box
            └── TextContainer
                └── TitleWrapper
                    └── Title

The goal is not maximum nesting.

The goal is a clear component hierarchy.

Child Components and Encapsulation

A useful benefit of child components is that they can hide implementation details.

For example:

function SearchBar() {
  const [query, setQuery] = useState("");

  return (
    <input
      value={query}
      onChange={(event) => {
        setQuery(event.target.value);
      }}
      placeholder="Search courses"
    />
  );
}

The parent only needs:

<SearchBar />

The parent doesn’t need to know how the search input manages its internal state.

This creates a useful separation:

Parent
   ↓
uses child

Child
   ↓
handles its own implementation

Child Components and State Sharing

A child should own state when that state is only relevant to the child.

For example, an input’s temporary UI state might belong inside the input component.

But suppose both SearchBar and CourseList need the search term:

Dashboard
├── SearchBar
└── CourseList

In that case, the shared state may belong in Dashboard.

function Dashboard() {
  const [search, setSearch] = useState("");

  return (
    <>
      <SearchBar
        value={search}
        onChange={setSearch}
      />

      <CourseList
        search={search}
      />
    </>
  );
}

The parent becomes the state owner.

This is known as lifting state up.

Child Components and Props Are Read-Only

Props received by a child should be treated as read-only.

For example:

function CourseCard({ title }) {
  return <h2>{title}</h2>;
}

The child should not try to directly modify the title prop.

If the child needs to request a change, the parent can provide a callback.

function CourseCard({ title, onRename }) {
  return (
    <button onClick={() => onRename("Advanced React")}>
      Rename
    </button>
  );
}

The parent controls how the change is handled.

This keeps React’s data flow predictable.

Child Components and children Are Different Concepts

A child component and the children prop are related but not identical.

Consider:

<Card>
  <CourseDetails />
</Card>

CourseDetails is a component nested inside Card.

Card receives that nested content through its children prop.

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

So:

CourseDetails
       ↓
passed as children
       ↓
Card

The children prop is a mechanism for passing nested content.

A Complete Learning Platform Example

Imagine a course dashboard:

CourseDashboard
├── CourseHeader
├── CourseProgress
├── LessonList
│   ├── LessonItem
│   ├── LessonItem
│   └── LessonItem
└── InstructorCard

The parent might look like:

function CourseDashboard() {
  return (
    <main>
      <CourseHeader />

      <CourseProgress />

      <LessonList />

      <InstructorCard />
    </main>
  );
}

LessonList becomes another parent:

function LessonList() {
  return (
    <section>
      <LessonItem title="Introduction to React" />
      <LessonItem title="Understanding JSX" />
      <LessonItem title="Working with Props" />
    </section>
  );
}

And each LessonItem is a child:

function LessonItem({ title }) {
  return (
    <article>
      <h3>{title}</h3>
      <button>
        Start Lesson
      </button>
    </article>
  );
}

The final hierarchy is:

CourseDashboard
├── CourseHeader
├── CourseProgress
├── LessonList
│   ├── LessonItem
│   ├── LessonItem
│   └── LessonItem
└── InstructorCard

Each component has a focused responsibility.

Common Mistakes with Child Components

Trying to Modify Props Directly

Avoid treating props as variables that the child can change.

Use callbacks when a child needs to request a change.

Putting Too Much Responsibility in a Child

A child shouldn’t automatically handle unrelated application logic just because it is rendered inside a parent.

Creating Unnecessary Child Components

Don’t extract every small JSX element into a component without a useful reason.

Passing Unnecessary Props

Only provide the child with the information it actually needs.

Keeping Shared State Inside One Child

If multiple components need the same state, consider moving it to their closest common parent.

Confusing a Child Component with the children Prop

A child component is a component in the hierarchy.

children is a prop containing nested content.

They are related concepts, but they are not the same thing.

Assuming Children Automatically Share State

Two child components don’t automatically share state just because they have the same parent.

Shared state must be deliberately managed and passed where needed.

Best Practices for Child Components

Keep Children Focused

Give each child a meaningful responsibility.

Use Props for Input

Receive data through props rather than hardcoding values.

Use Callbacks for Events

Let parents provide functions when children need to trigger parent-controlled behavior.

Keep Local State Local

If state only belongs to the child, keeping it inside the child can simplify the application.

Lift Shared State When Necessary

When multiple components need the same state, move it to an appropriate common parent.

Make Children Reusable Where It Makes Sense

Components such as:

Button
Card
Input
Modal
CourseCard
LessonItem
Avatar
ProgressBar

are often good candidates for reuse.

Keep the Component Tree Understandable

A child hierarchy should help developers understand the interface rather than make it harder to follow.

Image Placement

Place this image immediately after the section “Child Components Receive Props.”

Create a modern 16:9 React infographic showing a parent component passing different props to multiple child components.

The visual should show:

                  Parent
                    │
          ┌─────────┼─────────┐
          ↓         ↓         ↓
       Child A   Child B   Child C
          │         │         │
       title      user      progress
       prop       prop        prop

Also show a subtle return path where a child triggers a callback back toward the parent.

Use a modern developer-focused aesthetic, polished component cards, clean typography, subtle connecting lines, React-inspired visual details, and minimal text. Make the parent-child relationship immediately understandable.

Caption: Child components receive data through props and can trigger parent-provided callbacks.

Alt text: React parent component passing props and callbacks to multiple child components.

Practice Exercise

Build a course dashboard containing:

CourseDashboard
├── CourseHeader
├── CourseProgress
├── LessonList
│   ├── LessonItem
│   ├── LessonItem
│   └── LessonItem
└── InstructorCard

Create a reusable LessonItem component:

function LessonItem({
  title,
  completed,
  onSelect
}) {
  return (
    <article>
      <h3>{title}</h3>

      <p>
        {completed
          ? "Completed"
          : "Not completed"}
      </p>

      <button onClick={onSelect}>
        Open Lesson
      </button>
    </article>
  );
}

Then create a parent LessonList that renders multiple LessonItem components.

Pass:

  • Lesson title
  • Completion status
  • A callback for selecting a lesson

Then let CourseDashboard keep track of the selected lesson.

Your final data flow should look like:

CourseDashboard
       │
       ├── selectedLesson state
       │
       ↓
   LessonList
       ↓
   LessonItem
       │
       ↓
    onSelect
       │
       └────────→ CourseDashboard

This exercise will help you understand how child components receive information from parents and communicate events back to them.

Child Components Cheat Sheet

ConceptMeaning
Child componentComponent rendered by another component
ParentComponent that renders the child
PropsData passed from parent to child
CallbackFunction passed from parent to child
childrenNested content received through a special prop
Local stateState managed inside the child
Shared stateState needed by multiple components
Lifting state upMoving shared state to a common parent
Component treeHierarchy created by nested components

A simple mental model is:

Parent
   │
   ├── passes data
   ↓
Child
   │
   └── triggers callback
          ↓
        Parent

For normal data:

Parent
   ↓
Props
   ↓
Child

For events:

Parent
   ↓
Callback
   ↓
Child
   ↓
User interaction
   ↓
Callback

For shared state:

       Common Parent
        /         \
       ↓           ↓
   Child A      Child B
       ↑           ↑
       └─ shared state ─┘

Key Takeaways

  • A child component is a component rendered by another component.
  • Child components are an essential part of React’s component hierarchy.
  • A child can receive data from its parent through props.
  • Props should be treated as read-only by the child.
  • Parents can pass callback functions to children.
  • Children can trigger those callbacks to communicate events back to parents.
  • Child components can have their own state.
  • Each rendered instance of a child can have independent state.
  • The children prop allows components to receive nested content.
  • Shared state can be moved to a common parent when multiple children need it.
  • Child components should have clear and focused responsibilities.
  • Reusable child components help prevent duplicated UI code.
  • Avoid unnecessary nesting and unnecessary child components.
  • A good child component hides implementation details while exposing a simple interface to its parent.

The core idea to remember is:

A child component focuses on its own UI and behavior while receiving the data and instructions it needs from its parent.

Leave a Comment