React Props Deep Dive
A masterclass tutorial covering What are Props, Passing & Receiving Props, Destructuring, Default Values, Read-Only Immutability, Passing Objects, Arrays, Functions (Callbacks), Components, the Children Prop, and Full Code Practice.
What are Props?
Props (short for *Properties*) are read-only inputs passed from a Parent Component down to a Child Component.
Analogy:
Think of props like arguments passed into a JavaScript function.
Just as function add(a, b) receives arguments a and b to perform work, a React component <ProductCard name="iPhone" price={79999} /> receives props to render dynamic UI content.
Passing and Receiving Props
- Passing Props (in Parent Component):
You pass props into a component using HTML-like attribute syntax:
<ProductCard name="iPhone 15 Pro" price={79999} category="Mobile" />
- Receiving Props (in Child Component):
The child component receives a single object argument (conventionally named props) containing all passed attributes:
function ProductCard(props) {
return (
<div>
<h3>{props.name}</h3>
<p>Price: โน{props.price}</p>
<span>Category: {props.category}</span>
</div>
);
}Destructuring Props
Instead of typing props.name, props.price, and props.category repeatedly, modern React developers use ES6 Object Destructuring directly inside the function signature.
// Cleaner & Most Popular Syntax:
function ProductCard({ name, price, category }) {
return (
<div className="card">
<h3>{name}</h3>
<p>Price: โน{price}</p>
<span>{category}</span>
</div>
);
}Default Prop Values
You can specify Default Values for props in case the parent component forgets to pass them.
// Assigning Default Values via Destructuring:
function ProductCard({ name, price, category = "General Electronics", isAvailable = true }) {
return (
<div className="card">
<h3>{name}</h3>
<p>Price: โน{price}</p>
<p>Category: {category}</p>
<p>Status: {isAvailable ? "In Stock โ
" : "Out of Stock โ"}</p>
</div>
);
}Props are Read-Only (Immutability)
GOLDEN RULE OF REACT: Props are Immutable (Read-Only). A child component MUST NEVER attempt to mutate or modify its own props!
// โ WRONG (Mutating props throws errors or causes unexpected bugs)
function ProductCard(props) {
props.price = 50000; // NEVER DO THIS!
return <div>{props.price}</div>;
}Why are Props Read-Only?
React relies on Pure Functions. A component must behave like a pure function with respect to its props: given the same props, it must always render the exact same UI output.
Passing Data Types: Strings, Numbers, Booleans, Objects & Arrays
You can pass ANY JavaScript data type as a prop:
const productObj = { id: 101, brand: "Apple", rating: 4.8 };
const tagsArray = ["5G", "OLED", "A17 Pro"];
<ProductCard
name="iPhone 15 Pro" // String
price={79999} // Number (Wrapped in {})
isAvailable={true} // Boolean (Wrapped in {})
details={productObj} // Object (Wrapped in {})
features={tagsArray} // Array (Wrapped in {})
/>Passing Functions as Props (Callback Functions)
You can pass Functions as props! This allows a Child Component to communicate back up to its Parent Component.
// Parent Component (App.jsx)
function App() {
const handleAddToCart = (productName) => {
alert(`Added ${productName} to Cart!`);
};
return <ProductCard name="iPhone 15 Pro" onAddToCart={handleAddToCart} />;
}
// Child Component (ProductCard.jsx)
function ProductCard({ name, onAddToCart }) {
return (
<div>
<h3>{name}</h3>
<button onClick={() => onAddToCart(name)}>Add to Cart ๐</button>
</div>
);
}The Special children Prop
The children prop is a special built-in prop in React that receives whatever JSX elements are placed between the opening and closing tags of a custom component.
Creating Wrapper / Container Components:
// CardWrapper Component
function ContainerCard({ children, title }) {
return (
<div style={{ border: "2px solid #2506ad", borderRadius: "16px", padding: "20px" }}>
<h2 style={{ color: "#2506ad" }}>{title}</h2>
<div className="card-body">
{children} {/* Renders inner nested JSX */}
</div>
</div>
);
}
// Usage in App.jsx:
export default function App() {
return (
<ContainerCard title="Featured Offer">
<p>Get 20% discount on all React & Full-Stack development courses!</p>
<button className="btn-buy">Claim Offer Now</button>
</ContainerCard>
);
}Common Mistakes with Props
- Mutating Props: Attempting
props.price = 1000. - Forgetting Curly Braces for Non-String Types: Writing
<Card price="79999" />passes the string"79999"instead of the number79999. - Misspelling Prop Names: Passing
<Card cost={100} />but reading{price}inside the child component (returnsundefined).
Top React Interview Questions on Props
Q1: What are Props in React?
*Answer*: Props (properties) are read-only data inputs passed from a parent component to a child component to configure its layout and behavior.
Q2: Can a child component modify its props?
*Answer*: No. Props are strictly immutable. To change data over time, the component should use State or ask the parent component to pass a new prop value.
Q3: What is the children prop?
*Answer*: children is a built-in prop that captures and renders whatever elements are nested inside the opening and closing tags of a component.
Practical Hands-On Exercise โ E-Commerce ProductCard Component
Here is a complete, production-ready React component demonstrating all prop types: strings, numbers, objects, arrays, functions, default values, and the children prop:
// Complete Masterclass Props Demo Component (src/App.jsx)
import React from 'react';
// 1. Reusable ProductCard Component
function ProductCard({
name,
price = 0,
category = "General",
isAvailable = true,
tags = [],
onAddToCart
}) {
return (
<div style={{ border: "1px solid #cbd5e1", borderRadius: "12px", padding: "20px", marginBottom: "15px", background: "#fff" }}>
<span style={{ background: "#2506ad", color: "#fff", padding: "2px 8px", borderRadius: "4px", fontSize: "12px" }}>
{category}
</span>
<h3 style={{ margin: "10px 0 5px 0", color: "#002057" }}>{name}</h3>
<p style={{ fontSize: "18px", fontWeight: "bold", color: "#059669" }}>โน{price.toLocaleString('en-IN')}</p>
<p>Status: {isAvailable ? "In Stock ๐ข" : "Out of Stock ๐ด"}</p>
<div style={{ display: "flex", gap: "6px", margin: "10px 0" }}>
{tags.map((tag, idx) => (
<span key={idx} style={{ background: "#f1f5f9", padding: "2px 8px", borderRadius: "4px", fontSize: "12px" }}>
#{tag}
</span>
))}
</div>
<button
onClick={() => onAddToCart(name)}
disabled={!isAvailable}
style={{
background: isAvailable ? "#2506ad" : "#cbd5e1",
color: "#fff",
border: "none",
padding: "10px 18px",
borderRadius: "6px",
cursor: isAvailable ? "pointer" : "not-allowed",
fontWeight: "bold"
}}
>
{isAvailable ? "Add to Cart ๐" : "Sold Out"}
</button>
</div>
);
}
// 2. Main App Parent Component
export default function App() {
const handleAddToCart = (item) => {
alert(`Added "${item}" to your shopping cart!`);
};
return (
<div style={{ maxWidth: "600px", margin: "30px auto", padding: "20px", background: "#f8fafc", borderRadius: "16px" }}>
<h2 style={{ color: "#002057" }}>Module 1 Complete: Masterclass Props Showcase</h2>
<ProductCard
name="iPhone 15 Pro Max"
price={159900}
category="Mobile Electronics"
isAvailable={true}
tags={["Apple", "Titanium", "A17 Pro", "5G"]}
onAddToCart={handleAddToCart}
/>
<ProductCard
name="MacBook Pro M3 Max"
price={319900}
category="Laptops"
isAvailable={false}
tags={["Apple", "M3 Max", "32GB RAM"]}
onAddToCart={handleAddToCart}
/>
</div>
);
}