← React for Beginners Checkpoint: the whole thing Optional · Lessons 7–12 · 10 questions Ten questions on state, forms, effects and where things belong. If the effects ones land, you finished the course with the mental model most people take a year to arrive at. 0 of 10 Answer one to start counting. Start over 01 What does this button do? <button onClick={handleClick()}>Click me</button> Calls handleClick when you click it Calls handleClick during render, not on click Nothing until you wrap it in an arrow function Throws a type error Right. The braces run their contents while the element is being described, so the call happens immediately and onClick receives the return value. Pass the function itself, or wrap it in an arrow when you need to pass arguments. Not this one. The braces run their contents while the element is being described, so the call happens immediately and onClick receives the return value. Pass the function itself, or wrap it in an arrow when you need to pass arguments. Lesson 7: Making it interactive: events and useState → 02 Clicking logs 1, then 2, then 3. The button still says 0. Why? function Counter() { let count = 0; function handleClick() { count = count + 1; console.log(count); } return <button onClick={handleClick}>Clicked {count} times</button>; } React batches the updates and keeps the last Nothing asked React to render again count needs to be a const The button is missing a key Right. Two problems that need one solution: a value that survives between renders, and one that tells React to render again when it changes. That pair is the entire reason useState exists. Not this one. Two problems that need one solution: a value that survives between renders, and one that tells React to render again when it changes. That pair is the entire reason useState exists. Lesson 7: Making it interactive: events and useState → 03 Counter keeps its count in useState. What happens if you use it twice? <Counter /> <Counter /> One count, shared between them Two counts, one per place it is used Two counts, and a warning about the duplicate Shared, if both are given the same props Right. State belongs to the place in the tree where the component is used, not to the function - exactly the way calling a function twice gives you two sets of local variables. Not this one. State belongs to the place in the tree where the component is used, not to the function - exactly the way calling a function twice gives you two sets of local variables. Lesson 7: Making it interactive: events and useState → 04 count is 0. What is it after this handler runs? setCount(count + 1); setCount(count + 1); setCount(count + 1); 3 1 2 It throws Right. count is a const captured for this particular render, so all three lines compute 0 + 1. Pass a function - setCount(c => c + 1) - when the next value depends on the previous one, and each call gets the result of the one before it. Not this one. count is a const captured for this particular render, so all three lines compute 0 + 1. Pass a function - setCount(c => c + 1) - when the next value depends on the previous one, and each call gets the result of the one before it. Lesson 7: Making it interactive: events and useState → 05 What makes an input controlled? Reading it with a ref when you need the value State sets its value, and onChange writes back Giving it a defaultValue instead Handling onSubmit on the form that wraps it Right. Both halves are needed. Once state is the only place the value lives, validation, a character count, a clear button and a disabled submit all become ordinary reads of a variable. Not this one. Both halves are needed. Once state is the only place the value lives, validation, a character count, a clear button and a disabled submit all become ordinary reads of a variable. Lesson 8: Forms and controlled inputs → 06 There is no email in state yet. What does React say when you start typing? const [form, setForm] = useState({}); <input value={form.email} onChange={handleChange} /> Nothing. undefined counts as an empty string That an uncontrolled input became controlled That value has to be a string It throws, and the field stops accepting input Right. value={undefined} means uncontrolled, so the input manages itself until the first keystroke puts a real string in state - at which point it silently becomes controlled and React complains. Initialise every field you intend to control, even the empty ones. Not this one. value={undefined} means uncontrolled, so the input manages itself until the first keystroke puts a real string in state - at which point it silently becomes controlled and React complains. Initialise every field you intend to control, even the empty ones. Lesson 8: Forms and controlled inputs → 07 A search box holds the query in its own state. The list that needs it is a sibling, not a child. Where should the query live? In both of them, kept in step In the closest component containing both In a context, so anything can read it In a variable outside both components Right. Data flows down, never up or sideways, so a sibling has no way to see it. The parent holds it and hands one child the value and the other a function to change it. Most apps need this far more often than they need context. Not this one. Data flows down, never up or sideways, so a sibling has no way to see it. The parent holds it and hands one child the value and the other a function to change it. Most apps need this far more often than they need context. Lesson 9: Sharing state between components → 08 What does an empty dependency array actually mean? useEffect(() => { ... }, []); Run this on mount This depends on nothing, so it never re-runs Run this once for the lifetime of the app Run this after every render Right. The distinction sounds pedantic and is the whole lesson. Read as a dependency list, the cleanup function and StrictMode's double-run both stop being surprises. Read as on mount, every effect you write is a lifecycle method wearing a disguise. Not this one. The distinction sounds pedantic and is the whole lesson. Read as a dependency list, the cleanup function and StrictMode's double-run both stop being surprises. Read as on mount, every effect you write is a lifecycle method wearing a disguise. Lesson 10: Talking to the outside world: useEffect and fetching → 09 A console.log inside an effect fires twice in development. Why? Something is wrong with the dependency array StrictMode runs it, cleans up, and runs it again The component renders twice, so everything does A known bug in React 19 Right. It runs the pair twice on purpose, to surface exactly the bug a missing cleanup causes. An effect that sets something up and never tears it down will visibly do it twice, in development, instead of leaking in production where you would never see it. Not this one. It runs the pair twice on purpose, to surface exactly the bug a missing cleanup causes. An effect that sets something up and never tears it down will visibly do it twice, in development, instead of leaking in production where you would never see it. Lesson 10: Talking to the outside world: useEffect and fetching → 10 books is in state, and the page also shows how many are unread. Where should that number come from? const [books, setBooks] = useState(initialBooks); // books[n].read is true or false. Where does the unread count come from? An effect that recalculates it when books changes A second piece of state, updated alongside books A calculation during render, from books State, wrapped in useMemo Right. The test is: could I work this out from something else I already have? If yes, it is not state. A count recalculated every render cannot drift; a stored copy of the same fact eventually disagrees with the thing it was copied from. Not this one. The test is: could I work this out from something else I already have? If yes, it is not state. A count recalculated every render cannot drift; a stored copy of the same fact eventually disagrees with the thing it was copied from. Lesson 11: Thinking in React: build the whole thing → ← All lessons Get in touch