
ReactJS
Both props and state hold data, but they serve completely different purposes. Props come from outside, state lives inside. Understanding which to use is the foundation of thinking in React.
Props = Data passed DOWN from parent (immutable, you don't control it)
State = Data owned BY component (mutable, the component controls it)
Think of props as function parametersβthe parent decides them. Think of state as local variables that the component manages internally.
function Parent() {
// State: parent owns this, can change it
const [count, setCount] = useState(0);
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
{/* Props: passed to child, child sees it but can't change it */}
<Child message={`Parent count is ${count}`} />
</>
);
}
function Child({ message }) {
// message is a prop - we receive it but can't modify it
return <p>{message}</p>;
}<details>
<summary>π More Examples</summary>
// Product list: parent has state, passes props to children
function ProductList() {
const [selectedId, setSelectedId] = useState(null);
const products = [
{ id: 1, name: "Laptop", price: 999 },
{ id: 2, name: "Mouse", price: 25 },
];
return (
<div>
{products.map(product => (
<ProductCard
key={product.id}
name={product.name}
price={product.price}
isSelected={selectedId === product.id}
onSelect={() => setSelectedId(product.id)}
/>
))}
</div>
);
}
function ProductCard({ name, price, isSelected, onSelect }) {
// All of these are props - this component doesn't own them
return (
<div onClick={onSelect} style={{ borderWidth: isSelected ? 2 : 0 }}>
<h3>{name}</h3>
<p>${price}</p>
</div>
);
}</details>
Use props when the data comes from a parent component and doesn't change within this component:
function Button({ text = "Click me", color = "blue" }) {
// text and color are props - parent defines them
// This component just displays them, doesn't change them
return <button style={{ background: color }}>{text}</button>;
}<details>
<summary>π More Examples</summary>
// UserCard doesn't own the user data - parent passes it
function UserCard({ name, email, avatar }) {
return (
<div>
<img src={avatar} alt={name} />
<h3>{name}</h3>
<p>{email}</p>
</div>
);
}
<UserCard
name="Alice"
email="alice@example.com"
avatar="/alice.jpg"
/></details>
Use state when the component manages data that can change over time:
function Counter() {
// count is state - this component owns and controls it
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}<details>
<summary>π More Examples</summary>
// SearchBox manages its own input value
function SearchBox() {
const [query, setQuery] = useState("");
return (
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
);
}
// Form tracks multiple input values
function LoginForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
// Do something with email and password
};
return (
<form onSubmit={handleSubmit}>
<input value={email} onChange={(e) => setEmail(e.target.value)} />
<input value={password} onChange={(e) => setPassword(e.target.value)} type="password" />
<button>Login</button>
</form>
);
}</details>
| Aspect | Props | State |
|---|---|---|
| Owned by | Parent | Component itself |
| Can change | β No | β Yes |
| Who controls it | Parent | Component |
| Triggers re-render | When parent updates | When you call setState |
| Use for | Configuring component | Tracking changing data |
Ready to practice? Challenges | Next: Passing Functions as Props
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