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
| Concept | Meaning |
|---|---|
| Child component | Component rendered by another component |
| Parent | Component that renders the child |
| Props | Data passed from parent to child |
| Callback | Function passed from parent to child |
children | Nested content received through a special prop |
| Local state | State managed inside the child |
| Shared state | State needed by multiple components |
| Lifting state up | Moving shared state to a common parent |
| Component tree | Hierarchy 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
childrenprop 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.