Study notes
Synchronize with timers and requests, and clean up after them.
Read the explanation, run the worked example, then complete the matching Examples and Assignments tabs. Your original materials remain available alongside these notes.
Understand the idea
Rendering calculates UI. An effect handles an external system such as a timer or request after a commit. Return cleanup that reverses the setup. With dependencies, React cleans up the previous effect before setting up the next version when those values change. Development Strict Mode intentionally exercises setup and cleanup again.
For your clock, an interval updates state and cleanup clears it. For a countries request, represent loading, success and error separately, check response.ok, and cancel an obsolete request. A click-specific alert belongs in the click handler; using an effect only to notice that a click changed state introduces unnecessary indirection.
Run the example
Use a separate React practice project with a Node.js version supported by Vite. Create it once with these commands, then use its development URL. Do not paste this into the Edupoly website’s own source files.
npm create vite@latest react-practice -- --template react
cd react-practice
npm install
npm run dev
Replace src/App.jsx with the following complete example. Keep Vite’s generated src/main.jsx entry point.
src/App.jsx
import { useEffect, useState } from 'react';
export default function App() {
const [now, setNow] = useState(() => new Date());
useEffect(() => {
const timer = setInterval(() => setNow(new Date()), 1000);
return () => clearInterval(timer);
}, []);
return <time>{now.toLocaleTimeString()}</time>;
}
Expected result
The clock advances every second. Removing the component clears its interval.
Alternative worked example — replace src/App.jsx
For a local request fixture, create public/countries.json containing the following JSON. You can later replace the URL with your Countries API and adapt its response format.
[{"id":"IN","name":"India"},{"id":"JP","name":"Japan"}]import { useEffect, useState } from 'react';
export default function Countries({url = '/countries.json'}) {
const [result, setResult] = useState({loading: true, rows: [], error: ''});
useEffect(() => {
const controller = new AbortController();
let active = true;
setResult({loading: true, rows: [], error: ''});
async function load() {
try {
const response = await fetch(url, {signal: controller.signal, headers: {Accept: 'application/json'}});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const rows = await response.json();
if (!Array.isArray(rows)) throw new Error('Expected an array');
if (active) setResult({loading: false, rows, error: ''});
} catch (error) {
if (active && error.name !== 'AbortError') setResult({loading: false, rows: [], error: error.message});
}
}
load();
return () => { active = false; controller.abort(); };
}, [url]);
if (result.loading) return <p>Loading countries…</p>;
if (result.error) return <p role="alert">{result.error}</p>;
return <ul>{result.rows.map(row => <li key={row.id}>{row.name}</li>)}</ul>;
}
Apply this to your assignments
Complete the clock and increment exercises, then use the request pattern below for your Countries API. Provide your own endpoint with an array of {id,name} records or adapt the response mapping. Test offline mode and a failed status.
Your existing examples
- UseEffect with DepArray Refactoring Component
- API Calls with headers using fetch inside useEffect hook
Open the Examples tab to run or inspect these supplied projects. Their original links are preserved.
Open Assignments for your complete original worksheet and submission controls.
Common mistakes
Do not make the effect callback itself async: it must return cleanup, not a promise. Never put private API keys in browser code.
Check your understanding
- Predict the output before running the example, then compare it with the result panel.
- Explain which value each expression reads and which action changes it.
- Try the boundary cases listed in the practice task and record what you observe.
- Rebuild one matching assignment without copying, then compare behavior with the original example.
Reference
Official documentation for this topic · Vite setup requirements
