Replies: 2 comments 8 replies
-
Thanks for the question! While your question is specifically about the hydration, I wanted to address the more general question of "how do you keep the browser interactive" since the answer is the same for multiple features. So I'll split my answer into:
How can React keep the browser responsive?Conceptually, you can think of React rendering algorithm like this: while (hasMoreComponents) {
renderNextComponent()
} Here, "render" means calling your component function and putting DOM changes into a queue. When we run out of components (when we've walked the entire tree affected by a state update), we actually update the DOM. This is a synchronous render. In React 18, we have a new concept of "concurrent" renders. They look more like this: while (hasMoreComponents && !hasOtherStuffToDo) {
renderNextComponent()
} The new thing is that between each call to a component function, we check if we have something more important to do. We'd periodically set this flag to (Note: the reality is a bit more nuanced but this is a decent approximation.) By default, we use the first (non-interruptible) algorithm. The second (interruptible) algorithm kicks in for:
So this is how it works. We can't "pause" or "interrupt" JS code that already executes. That's not possible. But we can choose to stop a render pass and do something else instead (e.g. render another update or let the browser paint) before calling the next component. In React, each individual component usually takes very little time to render (< 1 ms). This is because component's rendering time does not include its children. JSX is lazy, so This was a general answer about how it's possible for React to interrupt execution. Now onto your more specific question. What happens when you set parent state before a sibling gets hydrated?
I should clarify that granularity of hydration is determined by the So coming back to your question, let's say you're speaking about subtrees of A and B rather than individual components A and B.
If component A updates its own state X, then it won't affect B since B is not a child of A. If component A updates a parent state X, what happens depends on where the component B is:
|
Beta Was this translation helpful? Give feedback.
-
If the update is fully within plain React patterns like calling setState or dispatch in a callback that updates a parent and passes it down, then what @gaearon said in the last scenario applies. However, @ad1992's question mentioned "subscribed". I suspect what is meant by that is something like a Flux-like subscription to an external store with short cuts to the tree. In that scenario where they're in separate Suspense boundaries it is possible for the tree to become inconsistent until it's fully hydrated. Because B won't be subscribed yet it won't know we have to update it and React doesn't know it'll eventually be there. So A updates but not yet B. However, there's another subtle scenario in this case where if React now tries to hydrate B, it can cause a hydration error if it reads from the external Flux store since it has changed. This is one of the concurrency scenarios that a new API called useMutableSource tries to address. Basically, we'd likely have to throw away the rendered HTML for B in this scenario and rerender it on the client. But we have to know that we should. useMutableSource lets us know whether a Flux store has changed since we started hydrating it. We also need to know about these at the root level when we start hydrating using external stores. |
Beta Was this translation helpful? Give feedback.
-
Thank you for creating an awesome post on Suspense SSR Architecture 💯 🎉
As mentioned in Suspense SSR Architecture
How do you make sure that the browser is still interactive during hydration? Is it like doing hydration in batches at some intervals?
Additionally, how would the below scenario get handled?
A
(hydrated so clickable now) and a componentB
which is still hydrating (both are siblings).Clicking on component
A
updates some stateX
whichB
is subscribed (an external store) to as well so If the user clicks on compA
. andB
is still hydrating so what will happen in this case ? will React not dispatch the event untilB
is hydrated?A
andB
are not siblings?Beta Was this translation helpful? Give feedback.
All reactions