Advanced Patterns — Series 2

Preview — 3 of 10 questions

key="a" disappeared and key="d" is new; b and c are present in both, just shifted position. What does React actually do to the DOM here?

javascript
// Before:
<ul>
  <li key="a">Apple</li>
  <li key="b">Banana</li>
  <li key="c">Cherry</li>
</ul>

// After:
<ul>
  <li key="b">Banana</li>
  <li key="c">Cherry</li>
  <li key="d">Date</li>
</ul>
AReact reuses the existing DOM nodes for b and c (moving them to their new position rather than recreating them), unmounts the node for a, and mounts a brand-new node for d
BReact discards all three old nodes and creates three entirely new ones, since the key set changed between renders
CReact keeps all four nodes (old a included) in the DOM, just visually hides the removed one with display: none
DBecause the key set changed, React falls back to index-based matching for the entire list, ignoring the key attributes altogether

In React 18+, how many renders does clicking trigger, given both setCount and setFlag are called inside the .then() callback of a Promise?

javascript
function handleClick() {
  fetchUser().then(() => {
    setCount(c => c + 1);
    setFlag(f => !f);
  });
}
ATwo renders — Promise callbacks execute outside of any React-managed event, so each setState call triggers its own separate render
BZero renders until the component unmounts and remounts, since async callbacks are considered "outside React" entirely
COne render — React 18's automatic batching groups state updates together across microtasks, timeouts, promises, and native event handlers, not just inside React's own synthetic event handlers like React 17 did
DIt depends on whether StrictMode is enabled — batching only applies in StrictMode

What specifically causes React to show <Spinner /> instead of <ProfileDetails />?

javascript
function ProfilePage() {
  return (
    <Suspense fallback={<Spinner />}>
      <ProfileDetails />
    </Suspense>
  );
}

function ProfileDetails() {
  const user = useUserData(); // throws a Promise while data is loading
  return <h1>{user.name}</h1>;
}
ASuspense polls ProfileDetails on an interval, checking a loading boolean prop
BAny error thrown by ProfileDetails, of any kind, is caught by the nearest Suspense boundary and treated as "still loading"
CProfileDetails must explicitly call a showFallback() API provided via context
DuseUserData throws a Promise (not a regular error) during render, and Suspense specifically recognizes a thrown Promise as "this subtree isn't ready yet" — it catches that Promise, renders the fallback, and re-attempts rendering the subtree once the Promise resolves

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.