Hands-on practice for this lecture. Work through the exercises and quizzes to reinforce what you've learned.
Exercise 1 of 2
Three useEffect patterns involving cleanup, AbortController, and race conditions. Identify what each pattern fixes and why.
useEffect(() => {
let ignore = false;
fetch(`/api/user/${id}`)
.then(r => r.json())
.then(data => {
if (!ignore) setUser(data);
});
return () => { ignore = true; };
}, [id]);What problem does the "ignore" flag solve?
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(r => r.json())
.then(setData)
.catch(err => {
if (err.name === 'AbortError') return;
setError(err);
});
return () => controller.abort();
}, []);What happens when the component unmounts before the fetch completes?
useEffect(() => {
const id = setTimeout(() => {
processQueue();
}, 500);
}, [queue]);What is wrong with this effect?
0/3 answered
Exercise 2 of 2
Live editor: clicking users quickly can show wrong data. Add an ignore flag to the fetch effect to protect against race conditions.
Task
Click the user buttons quickly. The displayed user can flicker or show the wrong person — a race condition. An older slow response can arrive after a newer fast one, overwriting the correct data.
Fix the effect using an ignore flag: set a boolean in the effect, check it before calling setUser, and set it to true in the cleanup so superseded responses are discarded.