One of the biggest advantages of React is the ability to create reusable components.
A reusable component is a component that can be used in multiple places without rewriting its implementation.
Instead of creating separate code for every button, card, input field, modal, or navigation item, you can create the component once and customize it when you use it.
For example, instead of writing three different buttons:
<button>Login</button>
<button>Sign Up</button>
<button>Start Learning</button>
you can create one reusable Button component:
function Button({ children }) {
return (
<button className="button">
{children}
</button>
);
}
Then reuse it:
<Button>Login</Button>
<Button>Sign Up</Button>
<Button>Start Learning</Button>
The implementation exists once, but the component can appear many times.
This is the foundation of reusable UI development in React.
What Is a Reusable Component?
A reusable component is a component designed to work in more than one place or with different data.
For example:
function CourseCard({ title, instructor }) {
return (
<article>
<h2>{title}</h2>
<p>{instructor}</p>
</article>
);
}
The same component can represent different courses:
<CourseCard
title="React Fundamentals"
instructor="Alex"
/>
<CourseCard
title="JavaScript Essentials"
instructor="Sarah"
/>
<CourseCard
title="CSS Mastery"
instructor="David"
/>
The structure stays the same.
Only the data changes.
This gives you a simple pattern:
One Component
↓
Different Props
↓
Multiple Uses
Why Reusable Components Matter
Imagine you have 20 course cards on a website.
Without reusable components, you might repeatedly write:
<article>
<img src="..." />
<h2>React Fundamentals</h2>
<p>Learn React.</p>
</article>
Then another:
<article>
<img src="..." />
<h2>JavaScript Essentials</h2>
<p>Learn JavaScript.</p>
</article>
And continue doing the same thing for every course.
This creates duplicated markup.
With a reusable component:
function CourseCard({ title, description }) {
return (
<article>
<h2>{title}</h2>
<p>{description}</p>
</article>
);
}
You can use it repeatedly:
<CourseCard
title="React Fundamentals"
description="Learn the fundamentals of React."
/>
<CourseCard
title="JavaScript Essentials"
description="Learn modern JavaScript."
/>
Now if the card structure needs to change, you can update the component once.
Reusability Through Props
Props are one of the main tools used to make components reusable.
Consider:
function UserCard({ name, role }) {
return (
<div className="user-card">
<h2>{name}</h2>
<p>{role}</p>
</div>
);
}
You can reuse it with different information:
<UserCard
name="Alex"
role="Frontend Developer"
/>
<UserCard
name="Sarah"
role="UI Designer"
/>
<UserCard
name="David"
role="Backend Developer"
/>
The component doesn’t need to know which user it will display.
The parent supplies the data.
Reusable Components Should Not Hardcode Everything
A component becomes less reusable when important information is hardcoded inside it.
For example:
function CourseCard() {
return (
<article>
<h2>React Fundamentals</h2>
<p>Learn React.</p>
</article>
);
}
This component is tied to one specific course.
A more reusable version is:
function CourseCard({ title, description }) {
return (
<article>
<h2>{title}</h2>
<p>{description}</p>
</article>
);
}
Now the component can represent many courses.
Reusable Components with children
The children prop is another powerful way to create reusable components.
For example:
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
Now the same Card component can contain different content.
<Card>
<h2>React Fundamentals</h2>
<p>Learn React step by step.</p>
</Card>
Another use:
<Card>
<h2>JavaScript</h2>
<p>Learn modern JavaScript.</p>
</Card>
Another:
<Card>
<h2>Your Progress</h2>
<p>You've completed 65% of this course.</p>
</Card>
The Card controls the outer structure while the parent controls its content.
Reusable Buttons
Buttons are one of the most common reusable components.
Instead of repeatedly styling buttons:
<button className="primary-button">
Start Learning
</button>
<button className="primary-button">
Continue Course
</button>
create:
function Button({ children }) {
return (
<button className="primary-button">
{children}
</button>
);
}
Then:
<Button>Start Learning</Button>
<Button>Continue Course</Button>
<Button>View Course</Button>
You can later add common behavior or styling to the Button component without changing every usage.
Reusable Components with Variants
Sometimes the same component needs different visual styles.
For example:
function Button({ children, variant = "primary" }) {
return (
<button className={`button button-${variant}`}>
{children}
</button>
);
}
Now:
<Button>
Start Learning
</Button>
uses the default variant.
You can create another style:
<Button variant="secondary">
View Details
</Button>
Or:
<Button variant="danger">
Delete Course
</Button>
The component remains the same while the variant prop controls its appearance.
This is generally better than creating:
PrimaryButton
SecondaryButton
DangerButton
GreenButton
BlueButton
RedButton
for every visual variation.
Reusable Input Components
Form controls are also excellent candidates for reusable components.
For example:
function Input({ label, type = "text", placeholder }) {
return (
<label>
<span>{label}</span>
<input
type={type}
placeholder={placeholder}
/>
</label>
);
}
You can reuse it:
<Input
label="Name"
placeholder="Enter your name"
/>
<Input
label="Email"
type="email"
placeholder="Enter your email"
/>
<Input
label="Password"
type="password"
placeholder="Enter your password"
/>
One component provides the common structure.
Props customize the individual field.
Reusable Components with Events
Reusable components can also receive event handlers through props.
Consider:
function Button({ children, onClick }) {
return (
<button onClick={onClick}>
{children}
</button>
);
}
The parent decides what happens when the button is clicked.
function App() {
function handleLogin() {
console.log("Login clicked");
}
return (
<Button onClick={handleLogin}>
Login
</Button>
);
}
Another parent can use the same component differently:
function App() {
function handleStartCourse() {
console.log("Starting course");
}
return (
<Button onClick={handleStartCourse}>
Start Course
</Button>
);
}
The button is reusable because its behavior is supplied by the parent.
Reusable Components with State
Reusable components can also manage their own state.
For example:
import { useState } from "react";
function LikeButton() {
const [liked, setLiked] = useState(false);
return (
<button onClick={() => setLiked(!liked)}>
{liked ? "Liked" : "Like"}
</button>
);
}
You can use it multiple times:
<LikeButton />
<LikeButton />
<LikeButton />
Each rendered instance can maintain its own state.
For example:
Course A → liked
Course B → not liked
Course C → liked
The state belongs to each component instance.
Reusable Components and Data
Reusable components become especially powerful when they receive data from arrays.
Consider:
const courses = [
{
id: 1,
title: "React Fundamentals",
instructor: "Alex"
},
{
id: 2,
title: "JavaScript Essentials",
instructor: "Sarah"
},
{
id: 3,
title: "CSS Mastery",
instructor: "David"
}
];
Create a reusable component:
function CourseCard({ title, instructor }) {
return (
<article>
<h2>{title}</h2>
<p>{instructor}</p>
</article>
);
}
Then render the cards from the data:
function CourseList() {
return (
<section>
{courses.map((course) => (
<CourseCard
key={course.id}
title={course.title}
instructor={course.instructor}
/>
))}
</section>
);
}
This gives you a powerful architecture:
Data
↓
CourseList
↓
CourseCard
↓
Different UI for each course
The component implementation is written once.
Reusable Components and Default Values
You can give props default values.
For example:
function Button({
children,
variant = "primary"
}) {
return (
<button className={`button ${variant}`}>
{children}
</button>
);
}
If no variant is supplied:
<Button>
Start Learning
</Button>
variant becomes "primary".
If a different variant is needed:
<Button variant="secondary">
Learn More
</Button>
This makes reusable components easier to use.
Reusable Components Should Have a Clear API
When you create a reusable component, think about the props it accepts as its API.
For example:
<CourseCard
title="React Fundamentals"
instructor="Alex"
progress={75}
/>
The component’s API is essentially:
CourseCard
├── title
├── instructor
└── progress
A good API should be:
- Clear
- Predictable
- Easy to use
- Consistent
- Flexible without being unnecessarily complicated
Avoid requiring ten different props when three meaningful props are enough.
Don’t Make Components Reusable Too Early
There is an important balance.
You don’t always need to build a highly generic component from the beginning.
Suppose you have one course card:
function CourseCard() {
return (
<article>
<h2>React Fundamentals</h2>
</article>
);
}
If you later discover that the same structure is needed in several places, you can make it reusable.
Reusability should solve a real need.
Creating an extremely abstract component before understanding the requirements can make your code harder to use.
Reusable Components vs Duplicate Components
Imagine you create:
ReactCourseCard
JavaScriptCourseCard
CSSCourseCard
If all three have almost identical structure, this may be unnecessary duplication.
A better approach may be:
CourseCard
with different props.
<CourseCard title="React Fundamentals" />
<CourseCard title="JavaScript Essentials" />
<CourseCard title="CSS Mastery" />
Use one component when the underlying UI structure is fundamentally the same.
When Components Should Not Be Reused
Not every similar-looking piece of UI should necessarily share a component.
Two components may look similar but have different responsibilities or behaviors.
For example:
ProductCard
CourseCard
They may both contain an image, title, description, and button, but their business logic could be completely different.
Forcing them into one extremely generic component may make the component difficult to understand.
A reusable component should have a meaningful abstraction, not merely similar HTML.
Reusable Components and Composition
Reusable components become even more powerful when combined with composition.
For example:
function Card({ children }) {
return (
<article className="card">
{children}
</article>
);
}
Then:
<Card>
<CourseCard />
</Card>
Or:
<Card>
<ProgressCard />
</Card>
Or:
<Card>
<InstructorCard />
</Card>
The same Card provides the outer structure while different components provide the content.
This gives you a powerful React pattern:
Reusable Components
+
Composition
↓
Flexible UI
Building a Reusable Modal
A modal is another good example.
Instead of creating separate modal components for every situation, create a reusable structure:
function Modal({ title, children, onClose }) {
return (
<div className="modal">
<div className="modal-content">
<header>
<h2>{title}</h2>
<button onClick={onClose}>
×
</button>
</header>
{children}
</div>
</div>
);
}
You could use it for a login form:
<Modal
title="Login"
onClose={handleClose}
>
<LoginForm />
</Modal>
Or for course information:
<Modal
title="Course Details"
onClose={handleClose}
>
<CourseDetails />
</Modal>
The modal structure is reusable while its content changes.
A Complete Learning Platform Example
Imagine Web4Learners has a dashboard containing course cards.
The reusable component might be:
function CourseCard({
title,
instructor,
progress,
image
}) {
return (
<article className="course-card">
<img src={image} alt={title} />
<div>
<h2>{title}</h2>
<p>Instructor: {instructor}</p>
<progress
value={progress}
max="100"
/>
<p>{progress}% complete</p>
</div>
</article>
);
}
Then the parent can provide different courses:
function CourseList() {
return (
<section>
<CourseCard
title="React Fundamentals"
instructor="Alex"
progress={75}
image="/react-course.jpg"
/>
<CourseCard
title="JavaScript Essentials"
instructor="Sarah"
progress={45}
image="/javascript-course.jpg"
/>
<CourseCard
title="CSS Mastery"
instructor="David"
progress={90}
image="/css-course.jpg"
/>
</section>
);
}
The component doesn’t care which course it displays.
Its responsibility is simply to display a course using the information it receives.
A Reusable Component Checklist
Before creating a reusable component, ask:
Does it appear more than once?
If the same UI is used in multiple places, reuse may make sense.
Does it have a clear responsibility?
A component should represent a meaningful UI or behavior.
Which values should be configurable?
These usually become props.
<Button variant="primary">
Login
</Button>
Which content should be flexible?
This may be a good use for children.
<Card>
<CourseDetails />
</Card>
Should the component manage its own state?
If the behavior belongs naturally to the component, local state may be appropriate.
Should events come from the parent?
If the parent needs to control what happens, pass event handlers through props.
Common Mistakes with Reusable Components
Hardcoding Important Values
Avoid:
function UserCard() {
return <h2>Alex</h2>;
}
when the component is intended to display different users.
Use props:
function UserCard({ name }) {
return <h2>{name}</h2>;
}
Creating Extremely Generic Components
Avoid trying to make one component handle every possible situation.
For example, a component with dozens of props can become harder to understand than several focused components.
Duplicating Similar Components
If several components have essentially the same structure, consider whether one reusable component with props would be clearer.
Passing Unnecessary Props
Don’t pass information the component doesn’t use.
Making Every Component Generic
Not every component needs to be reusable.
Some components exist specifically for one page or feature.
Reusing the Wrong Abstraction
Two components looking similar does not automatically mean they should be the same component.
Focus on shared responsibility and behavior, not just similar markup.
Best Practices for Reusable Components
Give Components Clear Names
Use names that communicate their purpose.
Good examples:
Button
CourseCard
UserAvatar
Modal
Input
ProgressBar
Avoid vague names such as:
Box
Thing
Component1
CustomUI
unless the name genuinely communicates the component’s purpose.
Keep Props Simple
Prefer:
<CourseCard
title="React"
progress={70}
/>
over a complicated configuration object when simple props are sufficient.
Use Sensible Defaults
Defaults make components easier to use.
function Button({
children,
variant = "primary"
}) {
// ...
}
Support Composition
Use children when flexible content makes sense.
Keep Responsibilities Focused
A Button should primarily be a button.
A CourseCard should primarily represent a course card.
Avoid turning reusable components into giant collections of unrelated functionality.
Image Placement
Place this image immediately after the section “What Is a Reusable Component?”
Create a modern 16:9 React infographic showing one reusable component being used multiple times with different props.
The visual should show:
CourseCard
/ | \
↓ ↓ ↓
React JavaScript CSS
Card Card Card
↑ ↑ ↑
Different Props / Data
Use a polished modern developer aesthetic with clean component cards, subtle connectors, React-inspired visual elements, and minimal text. Clearly communicate that one component implementation can generate multiple different UI instances.
Caption: Reusable React components can display different content through props while keeping the same UI structure.
Alt text: React reusable component showing one CourseCard component used with different course data.
Practice Exercise
Create a reusable CourseCard component.
It should accept these props:
title
instructor
progress
level
Start with:
function CourseCard({
title,
instructor,
progress,
level
}) {
return (
<article>
<h2>{title}</h2>
<p>Instructor: {instructor}</p>
<p>Level: {level}</p>
<p>{progress}% complete</p>
</article>
);
}
Then use the same component three times:
<CourseCard
title="React Fundamentals"
instructor="Alex"
progress={70}
level="Beginner"
/>
<CourseCard
title="JavaScript Essentials"
instructor="Sarah"
progress={45}
level="Intermediate"
/>
<CourseCard
title="Advanced React"
instructor="David"
progress={20}
level="Advanced"
/>
After that, improve your component by adding:
- A course image
- A progress bar
- A reusable
Button - A
variantprop for the button - A click handler
- A
children-basedCardwrapper
Your final goal is to build a small dashboard using several reusable components rather than duplicated JSX.
Reusable Components Cheat Sheet
| Concept | Meaning |
|---|---|
| Reusable component | Component designed to be used in multiple places |
| Props | Values used to customize a component |
children | Flexible content passed inside a component |
| Variant | A controlled variation of a component |
| Component API | Props and behavior exposed by a component |
| Local state | State managed by an individual component instance |
| Event prop | Callback passed into a component |
| Composition | Combining reusable components together |
A useful mental model is:
Reusable Component
↓
Props
↓
Different Data / Behavior
↓
Multiple UI Instances
For example:
<CourseCard title="React" />
<CourseCard title="JavaScript" />
<CourseCard title="CSS" />
One component.
Three different results.
Key Takeaways
- Reusable components let you write UI logic and structure once and use it multiple times.
- Props are one of the primary ways to customize reusable components.
- The
childrenprop is useful when a component needs flexible content. - Event handlers can be passed through props.
- Components can manage their own local state while remaining reusable.
- Variants allow one component to support controlled visual differences.
- Reusable components should have a clear and understandable API.
- Avoid hardcoding values that should be configurable.
- Don’t make every component unnecessarily generic.
- Similar-looking components don’t always need to be the same component.
- Reusability works especially well with composition, props, and data-driven rendering.
- Good reusable components are focused, predictable, and easy to customize.
The core idea is simple:
Write the component once, make it flexible with props and composition, and reuse it wherever the same responsibility is needed.