Props and state
Add state with useState
Remember a value between renders and request a new render through its setter.
State lets a component remember a value between renders. Without it, every render starts from scratch and the UI cannot react to what the user did last time.
Let’s add a counter with useState:
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
)
}
Click the button and the label goes from Count: 0 to Count: 1, then Count: 2, and so on.
useState(0) gives this component position an initial value. During a render, count is that render’s snapshot. Calling setCount() asks React to render again with a new value.
Notice that the setter does not change the existing count variable. React calls the component again and gives the next render its own value. If you log count immediately after setCount(count + 1), the log still shows the old number. That is expected.
Use state when information changes over time and affects what you render. Keep derived values as calculations:
const completed = tasks.filter(task => task.done).length
Storing completed in separate state would create two values that can disagree after a toggle.
State belongs to a component position. Render two <Counter /> components side by side and you get two independent counts, even though both call the same function.
My advice is to start with one piece of state per concern. You can combine related values into an object later when the model is clear.
You can also pass a function to setCount when the next value depends on the previous one: setCount(n => n + 1). That avoids stale snapshots when several updates happen quickly.
Try this: click one of two counters and confirm only that instance changes. Then log count right after setCount() and explain why it still shows the current render’s value.
Lesson completed