Skip to content
Chapter 24Lesson 7

Quiz - Hooks for holding state

Quiz progress

0 / 0

A component seeds its state by reading and parsing a draft out of localStorage. Which call does that read-and-parse work exactly once, on mount?

useState(parseDraft(getStoredDraft()))
useState(() => parseDraft(getStoredDraft()))
useState<Draft>(parseDraft(getStoredDraft()))

You’re holding the setTimeout ID that debounces a search input. Why is this a useRef and not a useState?

The JSX never reads the timer ID, so storing it in state would schedule a re-render that paints nothing new.
A timer ID is a number, and useState can only hold objects.
useRef survives re-renders while a useState value is reset to its initial value on each render.

A junior keeps fullName in its own useState and resyncs it with a useEffect watching firstName and lastName. Beyond the extra render, what is the more dangerous problem with this shape?

fullName is a second copy of data that already exists, kept current by hand — add a middleName and forget the dependency array, and it silently goes stale with no error.
String concatenation in an effect is too slow to run on every keystroke.
useEffect can only depend on one value, so watching both names is unsupported.

A list view has a search filter the user types into. A teammate argues it should live in the URL as ?q=... rather than in lifted useState. Which facts actually justify the URL home? Select all that apply.

After a refresh, the user expects their filter to still be applied.
A shared link should land the recipient on the same filtered view.
Two sibling components on screen both need to read the filter.
The filtered rows are expensive to recompute on every render.

A submit form tracks isSubmitting, isSaved, submitError, and more across separate useStates, and a bug lets the spinner stay on after a validation failure. What is the core reason modelling this as a useReducer with a single status field fixes the class of bug?

Combinations like “submitting and saved at once” become unrepresentable — there’s no value of status that means both — instead of merely discouraged.
A reducer is always fewer lines of code than the equivalent useState calls.
Putting the await inside the reducer guarantees the spinner is reset on every exit path.

A teammate proposes using crypto.randomUUID() instead of useId() to generate the id that links a <label> to its <input>, reasoning it’s “more unique.” What goes wrong?

It rolls a different value on the server and in the browser, so the rendered HTML and hydration disagree and React warns about a mismatch.
crypto.randomUUID() is too slow to call during render.
UUIDs contain characters that are invalid in an HTML id attribute.

Quiz complete

Score by topic