Checkpoint: React Fundamentals

This checkpoint is a review milestone that consolidates the React Fundamentals track — JSX, props, fragments, rendering, styling, Strict Mode, effect timing, and immutable state — through a hands-on build challenge and a short quiz. It confirms you can combine these ideas before moving on to deeper hooks.

Learn Checkpoint: React Fundamentals in our free React course — an interactive lesson with runnable examples, a practice exercise and a quick recall.

Part of the free React course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

JSX In Depth — JSX is sugar for createElement objects; {' '} embeds expressions; attributes are camelCase; return one root.

Props & One-Way Data Flow — read-only inputs flow down; events flow up via callbacks; children wraps content.

Fragments — group siblings with and add zero DOM nodes.

How Rendering Works — render builds a virtual DOM; reconciliation diffs it; only changes are committed; a re-render is not always a DOM update.

Styling — className , camelCase inline style objects, scoped CSS Modules, conditional classes.

Strict Mode — dev-only double-invoke surfaces impurity and missing cleanup.

useLayoutEffect vs useEffect — before paint vs after paint; measure-and-adjust layout in the pre-paint hook.

Immutable State Updates — never mutate; copy with spread; add/remove/update arrays with spread/filter/map.

🛠️ Build Challenge: A Tiny To-Do Model

Implement four pure, immutable helpers for a to-do list, then run the three steps. None of your helpers may mutate the list they receive — each returns a brand-new array. This mirrors exactly how you would update React state.

1. addTodo(list, text) — append {' '} using spread.

2. toggleTodo(list, id) — map the list, flipping done on the match.

3. removeTodo(list, id) — filter out that id.

4. summary(list) — return "DONE/TOTAL done" .

Order the lifecycle of one state update, the thread running through this whole track:

📋 Quick Reference

React.createElement calls returning plain element objects.

Down via props; events flow back up via callback props.

React compares by reference; a new value is how it detects the change and re-renders.

🔎 Predict-the-Output Self-Test

Guess each line before running it. This checks that reference equality and shallow copies really clicked.

1. Why must a component return one root element?

The return is a single expression compiling to one element. Group siblings in a fragment .

2. A child needs to tell its parent a value changed. How?

The parent passes a callback prop; the child calls it. Data flows down, events flow up.

No. React diffs the new tree and commits only the changes; an unchanged tree leaves the DOM alone.

4. You write items.push(x) then setState and nothing updates. Why?

Same reference — React bails out. Pass a new array: .

5. When does useLayoutEffect run relative to paint?

Synchronously before paint (useEffect runs after). Use it only for measure-and-adjust layout.

6. Why does an effect sometimes run twice in development?

Strict Mode double-invokes (run, cleanup, run) to surface missing cleanup. It is dev-only.

Practice quiz

What does JSX compile down to?

  • Raw HTML strings inserted into the DOM
  • Template literals evaluated at runtime
  • React.createElement calls that return plain element objects
  • A separate .html file loaded by the bundler

Answer: React.createElement calls that return plain element objects. JSX is syntactic sugar for React.createElement(...) calls, which return plain JavaScript objects describing the UI.

Why must a component's return contain a single root element?

  • Because the return is one expression that compiles to one element; group siblings in a fragment
  • Because React only renders the first element it finds
  • Because multiple roots make the DOM slower
  • Because className can only be applied to one node

Answer: Because the return is one expression that compiles to one element; group siblings in a fragment. A return is a single expression compiling to one element. Wrap multiple siblings in a fragment <>...</> to satisfy this.

How do props behave in React?

  • They are mutable and can be reassigned by the child
  • They flow up from child to parent automatically
  • They are global and shared across all components
  • They are read-only inputs that flow down from parent to child

Answer: They are read-only inputs that flow down from parent to child. Props are read-only. Data flows down via props; events flow back up via callback props.

A child needs to tell its parent that a value changed. What is the idiomatic way?

  • Mutate the prop directly inside the child
  • The parent passes a callback prop and the child calls it
  • Use a global variable both can read
  • The child re-renders the parent manually

Answer: The parent passes a callback prop and the child calls it. Data flows down, events flow up: the parent passes a callback prop, and the child invokes it to report the change.

What is a fragment used for?

  • To group sibling elements while adding zero extra DOM nodes
  • To add an extra wrapper div to the DOM
  • To memoize a component
  • To pass props to many children at once

Answer: To group sibling elements while adding zero extra DOM nodes. A fragment <>...</> groups siblings into one root without rendering any additional DOM node.

Does every re-render result in a DOM update?

  • Yes, every render rewrites the entire DOM
  • Only when state is an object
  • No; React diffs the new tree and commits only the changes
  • Only in production builds

Answer: No; React diffs the new tree and commits only the changes. React builds a virtual DOM, reconciles it against the previous tree, and commits only the differences. An unchanged tree leaves the DOM alone.

You call items.push(x) then setState, but nothing updates. Why?

  • push is asynchronous
  • The array reference is unchanged, so React bails out of the update
  • setState only works with numbers
  • You must call render() manually after push

Answer: The array reference is unchanged, so React bails out of the update. Mutating in place keeps the same reference. React compares by reference, so it skips the update. Pass a new array like [...items, x].

When does useLayoutEffect run relative to the browser paint?

  • After paint, like useEffect
  • Only on unmount
  • It never runs in development
  • Synchronously before paint

Answer: Synchronously before paint. useLayoutEffect runs synchronously before paint (useEffect runs after). Use it only for measure-and-adjust layout work.

Why does an effect sometimes run twice in development?

  • Because of a bug in React
  • Because Strict Mode double-invokes effects to surface missing cleanup
  • Because the dependency array is empty
  • Because useEffect always runs twice in every environment

Answer: Because Strict Mode double-invokes effects to surface missing cleanup. Strict Mode intentionally mounts, unmounts, and remounts in development (run, cleanup, run) to reveal effects that are missing cleanup. It is dev-only.

How do you apply an inline style object in JSX?

  • style='color: red' as a plain string
  • css={{ color: 'red' }}
  • style={{ color: 'red' }} with a camelCased object
  • inline-style='color: red'

Answer: style={{ color: 'red' }} with a camelCased object. Inline styles take an object with camelCased properties, e.g. style={{ backgroundColor: 'blue' }}. Use className for CSS classes.