Reusable React Components
Table of Contents + −
In the last lesson you learned React Component Composition. Once you build real screens, you notice the same piece of UI showing up again and again, so this lesson answers one question: how do you write it once and reuse it everywhere with different content?
🤔 Why Reusable Components?
Here is the pain. Say your app needs three buttons. One says “Save”. One says “Cancel”. One says “Delete”. The quick way is to write three separate components.
function SaveButton() { return <button className="btn">Save</button>;}
function CancelButton() { return <button className="btn">Cancel</button>;}
function DeleteButton() { return <button className="btn">Delete</button>;}See the problem? These three are almost the same.
- The only thing that changes is the word inside the button. The rest is copied.
- Now your designer says “make all buttons rounded with more padding”. So you have to edit all three by hand.
- Tomorrow you add a fourth button. So you copy and paste yet again.
- This is how small apps slowly turn into a mess.
The fix is one reusable component.
- You write the button once. Then you pass the changing part in from outside.
- One place to edit. Used many times.
🧩 What Makes a Component Reusable?
A reusable component does not lock in its own content. Instead it leaves a blank spot, and whoever uses it fills that spot in.
Think of a name tag at an event. The tag itself is always the same. Same shape. Same “HELLO my name is” printed on top. The only part that changes is the blank line where you write your name. The tag is the reusable component. The name you write is the data passed in.
In React, that data is passed in through props.
- A prop is a value you hand to a component when you use it. It is like writing a name on the blank tag.
- We will cover props in full detail in the next module. For now you just need to see the idea in action.
Note
Props are how a parent component sends data down into a child component. The child reads that data and shows it. Think of it as filling in the blanks of a template.
🛠️ Turning Three Buttons Into One
Let’s rewrite those three buttons as a single reusable Button. The changing part is the text. So the text becomes a prop called label.
function Button({ label }) { return <button className="btn">{label}</button>;}Let’s walk through it.
function Button({ label })defines one button component. The{ label }part pulls out thelabelprop that gets passed in.{label}inside the JSX drops whatever text was passed in right into the button.
So the component no longer decides what it says. The caller decides. Now you use the same component three times. Each time you give it a different label.
function Toolbar() { return ( <div> <Button label="Save" /> <Button label="Cancel" /> <Button label="Delete" /> </div> );}Each <Button /> is the same component. The label="..." is the value you pass in for that one use. Here is what shows up on the screen.
Output
[ Save ] [ Cancel ] [ Delete ]One component. Three buttons. And look how easy changes get now.
- Want a fourth? Just add
<Button label="Share" />. - Want every button rounded? Change the one
Buttonand all four update together. - That is the whole win, right?
🃏 A More Real Example: A Card
Buttons are simple because they only need one piece of data. Real UI usually needs a few. Take a product card on a store like Amazon.
- Each card has a title, a price, and a description.
- The layout is the same for every product. Only the data changes.
So you build one ProductCard and pass in several props.
function ProductCard({ title, price, description }) { return ( <div className="card"> <h3>{title}</h3> <p className="price">${price}</p> <p>{description}</p> </div> );}The component reads three props. They are title, price, and description. It places each one into the layout. Now you can show a whole shelf of products from the same component.
function Shop() { return ( <div className="shop"> <ProductCard title="Wireless Headphones" price={59} description="Soft ear cups and long battery life." /> <ProductCard title="Coffee Mug" price={12} description="Holds 350ml. Dishwasher safe." /> </div> );}Same ProductCard both times, with different data each time.
- If you later have a hundred products, this same component handles all of them.
- You will see how to loop over a list and show one card per item in the Lists module.
Tip
Notice that text props use quotes, like title="Coffee Mug". But the number price uses braces, like price={12}. Strings can sit in plain quotes. Anything that is not a string, such as a number, a true or false, or an array, must go inside braces. Braces also work for strings, but quotes are the simple way for them.
🎯 Keep Each Component Focused on One Job
There is one habit that keeps components truly reusable. Each component should do one job.
- A
Buttonshows a clickable button. AProductCardshows one product. - A good name usually tells you the one job. So if you cannot name a component without using “and”, it is probably doing too much.
Why does this matter for reuse?
- A component that does one small job fits in many places.
- A component that does five things only fits the exact spot it was built for. So you can never reuse it.
| Component | Its one job | Reusable? |
|---|---|---|
Button | Show a clickable button | Yes, anywhere |
Avatar | Show one user picture | Yes, anywhere |
ProfilePageWithSidebarAndButtons | Too many jobs | No, fits only one spot |
⚠️ Common Mistakes
A few things trip people up when they first build reusable components.
- Locking the content inside the component. If the text lives inside the component, you cannot change it from outside. So you cannot reuse it.
// ❌ Avoid: text is locked inside, only ever says "Save"function Button() { return <button className="btn">Save</button>;}
// ✅ Good: text comes from a prop, works for any buttonfunction Button({ label }) { return <button className="btn">{label}</button>;}- Making one giant component for everything. A single component that shows the header, the sidebar, and the footer cannot be reused. Break it into small focused pieces.
- Copying a component just to change one word. The moment you copy a component and edit a single value, stop. That value should be a prop instead.
- Forgetting the braces for non-string props. Writing
price="12"passes the text “12”, not the number 12. Useprice={12}for real numbers.
✅ Best Practices
Keep these habits and your components stay easy to reuse.
- Name the component after the thing it shows, not the page it lives on. Use
Card, notHomePageCard. - Pass the changing parts in as props. Keep the fixed layout inside the component.
- Give each component one clear job. If the name needs an “and”, split it.
- Start small. Build a tiny generic piece first. Then put many of them together.
🧩 What You’ve Learned
✅ A reusable component is written once and used many times with different content.
✅ The changing parts are passed in from outside as props, like writing a name on a blank tag.
✅ One Button or ProductCard replaces several near-identical components.
✅ Text props use quotes. Numbers and other values use braces, like price={12}.
✅ Keep each component focused on one job so it fits in many places.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What makes a React component reusable?
Why: A reusable component leaves blanks and lets the caller fill them in through props, instead of locking content inside.
- 2
You need three buttons that say 'Save', 'Cancel', and 'Delete'. What is the cleanest approach?
Why: One generic Button used three times with a different label prop means one place to edit and easy reuse.
- 3
How should you pass a number, like a price of 12, into a component?
Why: Non-string values like numbers go inside braces, so price={12} passes the actual number 12, not the text "12".
- 4
Why should a component focus on one job?
Why: A component with one clear job fits many spots and is easy to reuse, while a component doing many things fits only where it was built.
🚀 What’s Next?
You can build a reusable component now. The next step is keeping all these pieces tidy as your app grows. You will see where each component should live and how to organize them.