skip to content

On a server-rendered React 19 page, a user clicks a button before hydration has finished. What happens to that click, and what does React do about interactions that arrive during hydration?

level: seniorimportance: should knowfreq 46%

answer

  1. two different windows, not one
  2. listeners are on the root container
  3. user intent reorders the hydration queue
  4. the event is kept and re-dispatched
  5. native form and link behaviour still works

basics

~20 s

If hydrateRoot has already started, React captures the click on the root container, prioritizes hydrating the subtree the user touched, and replays the event once that subtree is ready. If the bundle has not executed yet, no listener exists and the click is lost.

solid answer

~50 s

There are two very different windows. Before `hydrateRoot` runs at all — the bundle is still downloading or parsing — React has no listeners anywhere, so a click on a React handler simply does nothing and is gone. Only native browser behaviour still works: a link navigates, a real `<form>` submits. Once hydration has begun, the picture improves. React's listeners live on the root container from the start, so it can capture a discrete interaction even for a subtree that has not been hydrated yet. React then does two things: it prioritizes hydrating the Suspense boundary the user actually interacted with, ahead of boundaries it was working on, and it replays the captured event against that subtree once it is ready. That is selective hydration. It is why interactivity feels ordered by user intent rather than by document order, and why the honest engineering answer to the gap is to shrink it, not to rely on replay.

go deeper

for a junior

Know that a server-rendered page can be visible before it is interactive, and that a click on a React handler in that window may do nothing.

for a middle

Explain that React's listeners sit on the root container, that Suspense boundaries hydrate independently, and that a captured interaction can be replayed once its subtree is ready.

for a senior

Separate the two windows explicitly and say what you would do about each — replay covers hydration in progress, nothing covers a bundle that has not executed, so the critical action degrades to native HTML.

for a principal

Own it as a product decision: define which interactions must survive the pre-hydration window, and hold the architecture to that rather than to a framework feature you cannot rely on.

## Two windows, not one "Before hydration finishes" hides an important boundary. Split it: 1. **Before the client bundle executes.** The HTML is painted, but no React code has run. There are no React listeners on anything. 2. **After `hydrateRoot` has started but before this particular subtree is hydrated.** React is running; this part of the tree is not ready yet. Only the second window is one React can do anything about, and conflating the two is the most common way this question is answered badly. ## Window one: the click is gone In the first window a click on a button whose behaviour lives in a React `onClick` handler does nothing at all and leaves no trace. React cannot queue what it never saw, and the browser does not hold interactions for a framework that has not loaded. What *does* survive is the browser's own behaviour. An `<a href>` navigates. A real `<form action="/search" method="get">` submits and the server responds. This is the entire argument for progressive enhancement in a server-rendered app: build the critical path out of elements that mean something without JavaScript, and the early window degrades instead of breaking. ## Window two: root listeners make capture possible React attaches its event listeners to the root container you passed to `hydrateRoot`, not to individual elements. That single fact is what makes the rest possible: from the moment hydration begins, an event anywhere inside the container reaches React, even if the specific component under the pointer has no in-memory tree yet. ## Selective hydration Since React 18, hydration is not one uninterruptible pass. Content inside a `<Suspense>` boundary hydrates as an independent unit, and React can hydrate boundaries one at a time, yielding to the browser between them rather than blocking the main thread for the whole tree. When a discrete interaction lands inside a boundary that has not hydrated yet, React reorders its own work: it hydrates the boundary the user touched with higher priority, ahead of whatever it was working through. The practical effect is that the part of the page a user is actually trying to use becomes interactive first, even if it sits last in the document. ## Event replay Prioritising the right subtree would still lose the click if React only started listening afterwards. It does not — the captured event is replayed against the newly hydrated tree, so the handler runs as though it had been ready. From the user's point of view the button was slow, not broken. Two caveats worth stating in an interview. First, replay targets discrete interactions such as clicks and key presses; do not build a design around replaying continuous streams like pointer movement. Second, replay does not make the interaction free of consequences: the handler runs later than the user expected, so anything with visible latency still feels slow, and an optimistic UI that assumed instant feedback will simply be late. ## Why this shapes design, not just trivia The existence of replay is a safety net, not a strategy. The levers that actually shrink the window are structural: fewer client components so there is less to hydrate; splitting the tree so the interactive parts hydrate early; making the primary action work as native HTML so it functions even in window one. A candidate who answers only "React replays it" has learned a feature. A candidate who says "replay covers the second window, nothing covers the first, so I make the critical action a real form" has designed for the failure. ## Debugging note This behaviour is easy to misread in the field. A click that appears to do nothing on a slow connection is usually window one — no listener yet — while a click that works after a visible delay is usually window two doing exactly what it is supposed to. Throttling the network in devtools and watching when the bundle finishes executing separates the two cases quickly.

  • Which kinds of events can you rely on React replaying, and which not?
    Rely on it for discrete interactions — clicks, key presses, the things a user does deliberately once. Do not design around replaying continuous streams such as pointer movement or scrolling, where replaying a backlog would be meaningless. If a gesture must not be missed, make it work without JavaScript rather than trusting replay.
  • What decides which Suspense boundary React hydrates first?
    By default React works through boundaries as they become ready. A discrete interaction overrides that ordering: the boundary the user touched is hydrated with higher priority so the part of the page they are trying to use becomes interactive first, regardless of where it sits in the document.
  • What still functions on the page before any React code has run?
    Whatever the browser implements natively — anchors navigate, real forms submit, checkboxes and text inputs accept input, video controls work. Nothing that lives in a React handler does. That asymmetry is the case for building the critical path out of genuine HTML elements rather than click handlers on divs.

saying these in an interview costs you the question

  • Claims every pre-hydration click is replayed regardless of timing
  • Thinks the browser queues events for a framework that has not loaded
  • Says React attaches listeners to each element during hydration
  • Believes hydration is one uninterruptible pass over the whole tree
  • Treats event replay as a substitute for reducing hydration work

context