Introduction
In the last lesson every CourseCard showed the same course, because the data was baked inside it. Props fix that: they are the arguments of a component. The parent passes values in, the component reads them and renders — the same card, now personalised for every student, every course, every product. (Roman Urdu: Props component ke arguments hain — parent data bhejta hai, component usay dikhata hai.)
Key points
- Passing props looks like HTML attributes:
<ProfileCard name="Ali" age={20} />. Text goes in quotes; numbers, booleans, arrays, objects and expressions go in curly braces —age="20"is the string "20",age={20}is the number 20. This is the exam point from the video. - The component receives one object: React collects all props into a single object and hands it to your function —
function ProfileCard(props)— and you readprops.name,props.age. - Destructuring is the clean way:
function ProfileCard({ name, age })unpacks the object at the door (the same destructuring from the JavaScript series), and the body usesnameandagedirectly.(Roman Urdu: Props object ko function ke darwaze par hi khol lo — andar saaf naam milenge.) - Props are READ-ONLY: a component must never change its own props. Props belong to the parent; the child may only read them. Trying to reassign a prop is a famous beginner error — React data flows down, never back up through props.
- One-way flow keeps apps sane: parent → child → grandchild. When a value is wrong on screen, you walk up the one road it travelled.
childrenis a special prop: whatever you put between a component's opening and closing tags arrives asprops.children— how wrapper components likeCardhold any content.- Prop drilling: passing a value through many layers that do not need it, just to reach a deep child — the pain that lesson 5.7 (useContext) solves.
Code examples
Example 1 — One card, three students
function ProfileCard(props) {
return (
<div className="card">
<h3>{props.name}</h3>
<p>Age: {props.age}</p>
<p>Course: {props.course}</p>
</div>
);
}
function App() {
return (
<div>
<ProfileCard name="Ali" age={20} course="React" />
<ProfileCard name="Fatima" age={22} course="JavaScript" />
<ProfileCard name="Usman" age={19} course="CSS" />
</div>
);
}What it does: App uses the same component three times, passing different props each time. Note the two kinds of values: name and course are strings in quotes, while age uses curly braces so it stays a real number.
What you will see: three different profile cards — Ali (20, React), Fatima (22, JavaScript) and Usman (19, CSS) — all from one component.
Example 2 — Destructuring: before and after
// Before: props. everywhere
function PriceTag(props) {
return <p>Rs {props.price} — {props.label}</p>;
}
// After: unpacked at the door
function PriceTag({ price, label }) {
return <p>Rs {price} — {label}</p>;
}What it does: Both components receive the same props object. The second one destructures it in the parameter list, so the body reads like plain variables. Same behaviour, cleaner code — this is the style you will see in every real project.
What you will see: identical output from both versions, e.g. "Rs 250 — Chai" when used as <PriceTag price={250} label="Chai" />.
Example 3 — The children prop: a wrapper that holds anything
function Card({ title, children }) {
return (
<div className="card">
<h3>{title}</h3>
<div className="card-body">{children}</div>
</div>
);
}
function App() {
return (
<Card title="Announcement">
<p>Class is at 10 AM tomorrow.</p>
<button>OK</button>
</Card>
);
}What it does: Card does not know or care what goes inside it. The paragraph and button written between <Card> and </Card> arrive as the children prop and are placed inside the card body — the pattern behind sidebars, modals and layout wrappers.
What you will see: a card titled "Announcement" containing the paragraph and the OK button, framed by the Card's own styling.
Quick recap
- Props are a component's arguments: the parent passes them like attributes; strings in quotes, everything else in
{ }. - Read them via the props object or destructure them in the parameters; props are read-only and data flows one way — down.
childrencarries whatever sits between a component's tags; passing data through many layers is prop drilling, solved later by Context.
Common mistakes
- Passing numbers as strings —
age="20"sends the text "20", andage + 1becomes "201". The fix: numbers (and booleans, arrays, objects) always go in curly braces:age={20}. - Trying to change props inside the child —
props.price = 300breaks the read-only rule and the one-way flow. The fix: the child reads props; changing data is the parent's job (with state, next lesson). - Forgetting that props arrive as ONE object — writing
function Card(name, age)never works; React calls your function with a single props object. The fix: one parameter — the object — then destructure it:function Card({ name, age }).
Practice
- Build a
ProductCardcomponent with destructured propsname,priceandinStock. Show the name, the price asRs {price}, and the text "Available" or "Sold out" from the boolean. Use it for three different products inApp. - Make a
Panelwrapper component that takes atitleprop andchildren, styled as a bordered box. Put two different contents inside two Panels — a short list in one, a paragraph and a button in the other.