1. What Are Props & Passing Props
Props (short for properties) are arguments passed into React components. Just like function arguments configure what a function does, props configure what a component displays.
<UserProfile name="Alex" role="Architect" level={5} isVerified={true} />
3. Accessing Props (Destructuring)
In modern React, we always destructure props directly inside the function parameters:
return (
<div>
<h2>{name} (Lvl {level})</h2>
<p>{role}</p>
{isVerified && <span>Verified</span>}
</div>
);
}
4. Props With Different Data Types
| Data Type | JSX Syntax Example | Description |
|---|---|---|
| String | title="Dashboard" | Passed in standard quotes |
| Number | count={42} | Passed inside curly braces |
| Boolean | isActive={true} or isActive | Passed inside curly braces or shorthand |
| Array | tags={['React', 'Next.js']} | Passed as JS array literal |
| Object | user={{ id: 1, name: 'Aarav' }} | Double curly braces (outer = JSX, inner = object) |
| Function | onClick={() => alert('Clicked!')} | Callback passed to handle child events |
5. Props Are Read-Only & Top-Down Data Flow
React follows strict unidirectional (top-down) data flow. A child component must NEVER modify its own props.
props.count = props.count + 1; // ❌ ERROR: Props are immutable!7. What Is State & useState Hook
Stateis a component's personal internal memory. Unlike local JavaScript variables that reset on every function run, state values are preserved across renders by React.
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
9. Updating State & Re-rendering
When you invoke a state updater like setCount(1), React schedules a re-render. The component function runs again with the new state value, diffs the Virtual DOM, and updates only the changed elements on the screen.
setCount(prev => prev + 1);11. Props vs State (Side-by-Side Comparison)
| Feature | Props | State |
|---|---|---|
| Origin | Passed in from Parent | Created inside Component |
| Mutability | Strictly Read-Only (Immutable) | Updated via setState |
| Purpose | Component configuration & communication | Dynamic data that changes over time |
| Triggers Re-render? | Yes, if parent passes new values | Yes, when setState is called |
12. Lifting State Up & Passing Functions
When two sibling components need to communicate, you move the state to their common parent. The parent passes the state value to one child, and a callback function to the other child:
export function App() {
const [query, setQuery] = useState("");
return (
<>
<SearchBar onSearch={setQuery} />
<SearchResults query={query} />
</>
);
}
14. State With Objects and Arrays
Never mutate objects or arrays in state directly. Always use the spread operator to create a fresh copy:
setUser(prev => ({ ...prev, role: "Lead Architect" }));
// Adding to an Array in State
setItems(prev => [...prev, "New Item"]);
15. Common Props & State Mistakes
- Direct state mutation:
items.push("new")will NOT trigger a re-render. Always usesetItems([...items, "new"]). - Calling setState synchronously in the component body: Causes infinite re-render loops. Put state setters inside event handlers or
useEffect. - Expecting state to update immediately on the next line: State setters are asynchronous; state only updates on the next render cycle.
16. Building an Interactive Component
Combining props and state allows you to create rich, interactive widgets:
const [isActive, setIsActive] = useState(defaultActive);
return (
<button
className={isActive ? "badge-active" : "badge-inactive"}
onClick={() => setIsActive(!isActive)}
>
{label}: {isActive ? "ON" : "OFF"}
</button>
);
}
17. Props & State Best Practices
- Keep state as local as possible; only lift state up when siblings genuinely need it.
- Derive values during render instead of creating redundant state (e.g.
const fullName = firstName + ' ' + lastName;). - Always treat props as immutable contract parameters.