Props and State
Props — Passing Data to Components
Props (short for properties) are the mechanism for passing data from a parent component to a child component. They are the equivalent of function arguments for components.
// Parent passes props
function App() {
return <UserCard name="Amara" role="Developer" score={88} />;
}
// Child receives props as the first argument
function UserCard(props) {
return (
<div>
<h2>{props.name}</h2>
<p>{props.role}</p>
<p>Score: {props.score}</p>
</div>
);
}
Destructuring Props
Destructuring props makes components cleaner:
function UserCard({ name, role, score }) {
return (
<div>
<h2>{name}</h2>
<p>{role}</p>
<p>Score: {score}</p>
</div>
);
}
Default Prop Values
Use default values in destructuring to handle missing props gracefully:
function Button({ label = "Click me", variant = "primary", disabled = false }) {
return (
<button className={`btn btn-${variant}`} disabled={disabled}>
{label}
</button>
);
}
// Both of these work:
<Button label="Sign Up" />
<Button /> // Uses all defaults
Props are Read-Only
A component must never modify its own props. Props flow in one direction — from parent to child. This is called one-way data flow and it makes applications predictable:
function BadComponent({ count }) {
count = count + 1; // WRONG — never mutate props
return <p>{count}</p>;
}
function GoodComponent({ count }) {
const displayCount = count + 1; // Correct — create a new value
return <p>{displayCount}</p>;
}
The children Prop
The special children prop lets you pass JSX between the opening and closing tags of a component:
function Card({ children, title }) {
return (
<div className="card">
<h3>{title}</h3>
<div className="card-body">{children}</div>
</div>
);
}
// Usage
function App() {
return (
<Card title="My Course">
<p>This content is passed as children.</p>
<button>Enrol Now</button>
</Card>
);
}
State — Data That Changes Over Time
While props are passed from outside, state is data that a component owns and manages internally. When state changes, React automatically re-renders the component to reflect the new state.
State is introduced via the useState hook (covered in detail in the next lesson). Here is a conceptual overview:
import { useState } from "react";
function Counter() {
// useState returns [currentValue, setterFunction]
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Props vs State
| Props | State | |
|---|---|---|
| Source | Passed from parent | Owned by the component |
| Mutable? | No — read-only | Yes — via setter function |
| Purpose | Configure a component | Track changing data |
| Triggers re-render? | When parent re-renders | When setter is called |
Lifting State Up
When two sibling components need to share state, the state is moved to their common parent:
function App() {
const [selected, setSelected] = useState(null);
return (
<>
<CourseList onSelect={setSelected} />
<CourseDetail course={selected} />
</>
);
}
function CourseList({ onSelect }) {
// onSelect is a function passed as a prop
return (
<ul>
<li onClick={() => onSelect({ id: 1, title: "HTML Basics" })}>HTML Basics</li>
<li onClick={() => onSelect({ id: 2, title: "CSS" })}>CSS</li>
</ul>
);
}
function CourseDetail({ course }) {
if (!course) return <p>Select a course</p>;
return <p>You selected: {course.title}</p>;
}
This pattern — lifting state up — is fundamental to React architecture.
Key Takeaways
- Props are data passed from parent to child components; they are read-only and flow in one direction
- Destructure props in the function signature for cleaner, more readable component code
- Default prop values handle missing props gracefully using destructuring defaults
- The special children prop lets you pass JSX content between a component's opening and closing tags
- State is data owned by a component that can change; changing state triggers a re-render
- When multiple components need shared data, lift state up to their nearest common parent
Practice Exercise
- Create a
CourseCardcomponent that acceptstitle,duration,level, andisEnrolledprops - Add a default value of
"Beginner"forlevel - Display a "Enrolled" badge only when
isEnrolledis true - Create an
Appcomponent that renders threeCourseCardcomponents with different props - Create a
Sectionwrapper component using thechildrenprop and wrap your cards in it
Try it yourself
Key Takeaways
- Props are read-only data passed from parent to child; they configure how a component appears and behaves
- Destructure props in function parameters for cleaner component code: function Card({ title, body }) {}
- Use default values in destructuring to handle optional props: function Button({ label = 'Click' }) {}
- The children prop receives JSX placed between a component's opening and closing tags
- State is data owned and managed by a component; changing state triggers React to re-render the component
- When siblings need shared data, lift state to their nearest common parent and pass it down via props
Quick Quiz
1.What is the main rule about props in React?
2.What is the children prop in React?
3.What is 'lifting state up' in React?
4.What happens when a component's state changes in React?
Ready to go further?
CareerEx gives you structured 12-week training, live classes every Saturday and Sunday, real tutor feedback, and a certificate. Join the next cohort.
Join CareerEx