
ReactJS
State is data that a component owns and can change. When state changes, React automatically updates the component to show the new values. Without state, components would always display the same thingβthey couldn't respond to user actions.
Props come from parents and never change. State is owned by the component and can change at any time. Think of props as instructions and state as the component's memory.
Props flow down from parent to child and never change within a component. State is stored inside the component and can be updated by the component itself. When state changes, React re-renders the component with new values.
// Props don't change - they come from parent
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
// State CAN change - it's owned by the component
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}<details>
<summary>π More Examples</summary>
// Example: Props vs State in a Login Form
// Props tell the form WHAT to do
function LoginForm(props) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<form onSubmit={(e) => {
e.preventDefault();
// State values get passed to parent's callback (prop)
props.onLogin({ email, password });
}}>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Login</button>
</form>
);
}
// Parent passes callback as prop, uses state internally
function App() {
const [user, setUser] = useState(null);
return (
<LoginForm onLogin={setUser} />
);
}</details>
Use state when the component needs to remember something that can change. Don't use state for values that come from a parentβuse props instead.
State tracks things like:
import { useState } from 'react';
function TodoApp() {
// Use state for things that change
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
return (
<div>
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="Add a todo"
/>
<button onClick={() => {
setTodos([...todos, inputValue]);
setInputValue('');
}}>
Add
</button>
<ul>
{todos.map((todo, i) => (
<li key={i}>{todo}</li>
))}
</ul>
</div>
);
}<details>
<summary>π More Examples</summary>
// Example: Toggle visibility with state
function Accordion() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? 'Collapse' : 'Expand'}
</button>
{isOpen && (
<div>
<p>This content appears and disappears!</p>
</div>
)}
</div>
);
}</details>
| Concept | Key Point |
|---|---|
| Props | Data from parent, read-only, don't change in component |
| State | Data owned by component, can change, triggers re-renders |
| When to Use State | Form inputs, toggles, user interactions, changing data |
| When NOT to Use State | Fixed data from parent, use props instead |
Ready to practice? Challenges | Next: useState Basics
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep β’ Build Real β’ Verify Skills β’ Launch Forward