😵 The Problem
Imagine you're building a product page.
You already have a reusable component:
function ProductCard() {
return (
<div>
<h2>iPhone 16</h2>
<p>$799</p>
</div>
);
}
Looks fine.
Until you need another product.
And another.
And another.
Suddenly you start doing this:
function ProductCardOne() {}
function ProductCardTwo() {}
function ProductCardThree() {}
💀 That's not reusable anymore.
The actual problem is simple:
The component needs different data each time.
So how do we give data to a component without duplicating the component itself?
👉 Props.
💡 The Solution: Props
Props are basically how a parent component passes data to a child component.
Think of them like function arguments.
Normal JavaScript:
function greet(name) {
return `Hello ${name}`;
}
greet("John");
React:
function User({ name }) {
return <h2>Hello {name}</h2>;
}
<User name="John" />
The idea is almost the same.
You're passing information into something that needs it.
🔥 Your First Real Prop
Let's make the product card reusable.
function ProductCard({ name, price }) {
return (
<div>
<h2>{name}</h2>
<p>${price}</p>
</div>
);
}
Now:
function App() {
return (
<>
<ProductCard name="iPhone 16" price={799} />
<ProductCard name="MacBook Air" price={999} />
<ProductCard name="AirPods Pro" price={249} />
</>
);
}
Same component.
Different data.
That's the whole point.
🧩 Props Can Be Different Types
Props aren't limited to strings.
You can pass numbers:
<ProductCard price={799} />
Booleans:
<ProductCard isAvailable={true} />
Arrays:
<ProductList items={products} />
Objects:
<UserCard user={user} />
Even functions:
<Button onClick={handleSave}>
Save
</Button>
That's where props become much more powerful than they initially look.
⚡ Why Do We Use {} Sometimes?
This confuses people a lot.
This:
<ProductCard name="iPhone" />
passes a string.
But this:
<ProductCard price={799} />
passes a JavaScript number.
And:
<ProductCard isAvailable={true} />
passes a boolean.
The {} basically tells JSX:
“Hey, this isn't a plain string. Evaluate this as JavaScript.”
So:
price="799"
is a string.
While:
price={799}
is a number.
That difference matters.
🔥 Passing Objects
Real applications usually deal with objects.
For example:
const user = {
name: "John",
role: "Frontend Developer",
experience: 4
};
You can pass the whole object:
<UserCard user={user} />
Then:
function UserCard({ user }) {
return (
<div>
<h2>{user.name}</h2>
<p>{user.role}</p>
<span>{user.experience} years</span>
</div>
);
}
Or destructure it immediately:
function UserCard({ user: { name, role, experience } }) {
return (
<div>
<h2>{name}</h2>
<p>{role}</p>
<span>{experience} years</span>
</div>
);
}
The second version is shorter, but don't overdo nested destructuring just to save a couple of lines.
Readable code wins.
🎯 Props + Children
Here's another pattern you'll use constantly.
Instead of creating a component that only accepts one specific piece of text:
function Card({ title }) {
return (
<div className="card">
<h2>{title}</h2>
</div>
);
}
You can make it more flexible with children:
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
Now:
<Card>
<h2>Profile</h2>
<p>Frontend Developer</p>
</Card>
The content between <Card> and </Card> becomes the children prop.
This is one of the foundations of component composition in React.
🧠 The Important Rule: Props Are Read-Only
This is a big one.
If a component receives:
function User({ name }) {
// ...
}
Don't do this:
function User({ name }) {
name = "Alex"; // ❌
}
Props are inputs.
The child component shouldn't directly modify them.
If the data needs to change, that's usually a job for state in the appropriate component.
For example:
function App() {
const [name, setName] = useState("John");
return <User name={name} />;
}
The parent owns the state.
The child receives the current value through props.
🔄 Props Flow Down
React follows a very useful mental model:
Parent → Child
For example:
App
↓
Dashboard
↓
UserCard
Data can flow down that component tree through props.
function App() {
const user = {
name: "John",
role: "Developer"
};
return <Dashboard user={user} />;
}
function Dashboard({ user }) {
return <UserCard user={user} />;
}
function UserCard({ user }) {
return <h2>{user.name}</h2>;
}
This is called one-way data flow.
And honestly, understanding this early will save you a lot of confusion later.
💡 Real Developer Insight
Here's where things get interesting in real projects.
Props are great.
Until you start doing this:
<App user={user} />
<Dashboard user={user} />
<Layout user={user} />
<Sidebar user={user} />
<UserMenu user={user} />
And suddenly five components are passing the same data just so one deeply nested component can use it.
That's called prop drilling.
Props aren't the problem here.
The problem is that the data probably belongs somewhere more accessible.
Depending on the situation, you might eventually use:
- React Context
- state management libraries
- better component composition
- restructuring the component tree
But don't jump to Context just because you passed a prop through two components.
A little prop passing is completely normal.
Solve the problem when it actually becomes a problem.
⚠️ Common Developer Mistakes
1. Mutating Props
function User({ name }) {
name = "Alex"; // ❌
}
Props should be treated as read-only.
2. Passing Everything
You don't need to send the entire application state into every component.
Bad:
<User
user={user}
products={products}
settings={settings}
notifications={notifications}
orders={orders}
/>
If the component only needs the user's name:
<User name={user.name} />
Keep the component's API focused.
3. Confusing Strings and JavaScript Values
<User age="25" />
That's a string.
<User age={25} />
That's a number.
Looks almost identical.
Behaves differently.
4. Using Props for Data the Component Should Own
If something is truly internal to the component, it may belong in state instead of props.
Props are for external input.
State is for internal changing data.
5. Overusing Prop Drilling
Passing props through one or two levels is normal.
Passing the same prop through eight components just to reach the bottom?
Yeah… that's when you should stop and rethink the structure.
0 Comments