← 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.

01 What does this button do?
<button onClick={handleClick()}>Click me</button>

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>;
}

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 />

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);

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?

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} />

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?

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(() => { ... }, []);

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?

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?

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 →