State
What is State?
State is an object that stores local data inside a component that can change over time. When state changes, React re-renders that component.
State vs Props
| Aspect | Props | State |
|---|---|---|
| Who controls it | Parent | The component itself |
| Can it be changed? | No (read-only) | Yes (with setState/useState) |
| Purpose | Configuration from outside | Internal data that changes |
| Initialization | Sent from the parent | Defined inside the component |
useState Hook
useState is the React Hook for declaring state in a function component.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click Me
</button>
</div>
);
}
useState(0) returns an array with two elements: the current state value and a function to change it.
Manipulating State with Update Functions
Use an updater function when the new state depends on the previous state.
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(prev => prev + 1);
const decrement = () => setCount(prev => prev - 1);
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
Using an updater function (prev => prev + 1) is safer than using the current value directly.
State as an Object
State can be an object, but it must be updated immutably.
function Profile() {
const [user, setUser] = useState({
name: "John",
email: "[email protected]",
});
const changeEmail = () => {
setUser({ ...user, email: "[email protected]" });
};
return (
<div>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
<button onClick={changeEmail}>Change Email</button>
</div>
);
}
Immutable Pattern with the Spread Operator
Always create a new copy of state when changing it. Do not mutate state directly.
function TodoList() {
const [todos, setTodos] = useState(["Learn React", "Build a Project"]);
const addTodo = (newTodo) => {
setTodos([...todos, newTodo]);
};
const removeTodo = (index) => {
setTodos(todos.filter((_, i) => i !== index));
};
return (
<ul>
{todos.map((todo, index) => (
<li key={index}>
{todo}
<button onClick={() => removeTodo(index)}>Delete</button>
</li>
))}
<button onClick={() => addTodo("New Todo")}>Add</button>
</ul>
);
}
Complete Counter Example
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div className="counter">
<h2>Counter: {count}</h2>
<button onClick={() => setCount(0)}>Reset</button>
<button onClick={() => setCount(prev => prev - 1)}>-</button>
<button onClick={() => setCount(prev => prev + 1)}>+</button>
</div>
);
}
export default Counter;
Summary
State allows React components to hold data that changes. Use useState to declare state, and always follow the immutable pattern when updating it.
The next chapter covers Event Handling — how to handle user interactions such as clicks, input, and submit.