2 · Build one skill at a time · 18 MIN
Respond to a click with state
State remembers a value between renders.
A local variable is recreated whenever a component renders; changing it does not ask React to update the screen. useState returns the current stored value and a setter. The click handler calls that setter, and React schedules another render. The functional update receives the previous value, so it is safe when the next value depends on the last. Pass a function to onClick rather than calling it during render.
Trace the initial value 0 into the paragraph. Click Add and follow previous => previous + 1. Observe that the next render receives a different count. Use Math.max(0, previous - 1) for the bounded decrement.
Before you start
Install Node.js 22.12+ (or a supported newer LTS). In a terminal run: npm create vite@latest codingneed-react -- --template react. Then cd codingneed-react, npm install, and npm run dev. Open the local URL printed by Vite. Replace src/App.jsx with ONE lesson example at a time. JSX renders a browser interface; it is not a plain console script.
File for this example: App.jsx
New words, explained
- state
- A value React stores for a component.
- hook
- A React function such as useState; call it at the top level.
- event
- A browser interaction such as a click.
Follow the example step by step
- Trace the initial value 0 into the paragraph.
- Click Add and follow previous => previous + 1.
- Observe that the next render receives a different count.
- Use Math.max(0, previous - 1) for the bounded decrement.
You are ready to move on when: Three Add clicks show 3. Removing from 0 still shows 0. Reset works after both adding and removing.
Read the example
import {useState} from 'react';
export default function App() {
const [count, setCount] = useState(0);
return <main><h1>Practice counter</h1><p aria-live="polite">{count} sessions</p>
<button onClick={() => setCount(previous => previous + 1)}>Add session</button>
<button onClick={() => setCount(0)}>Reset</button>
</main>;
}Check the expected output
The screen begins at 0 sessions. Each Add session click increments it. Reset returns to 0.
Your challenge
Add a Remove session button that decreases the count but never below zero. Verify repeated clicks and reset.
Solution cost: Discuss the operations in this small example; rendering and I/O costs depend on the host. time · Proportional to the example’s retained data. space
Common trap
onClick={setCount(count + 1)} calls the setter while rendering and can cause an infinite render loop.
Study the project implementation
import {useState} from 'react';
export default function App() {
const [count, setCount] = useState(0);
return <main><h1>Practice counter</h1><p aria-live="polite">{count} sessions</p>
<button onClick={() => setCount(previous => previous + 1)}>Add session</button>
<button onClick={() => setCount(0)}>Reset</button>
</main>;
}Further reading: Official documentation
Next lesson: Make an input and a form work together →