-
Notifications
You must be signed in to change notification settings - Fork 47.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add renderToMarkup for Client Components #30121
Conversation
This lets you use renderToMarkup in a Client Component environment as a replacement to renderToStaticMarkup.
That way we can have separate configurations for legacy renderers (renderToString/renderToStaticMarkup) and the modern renderToMarkup.
Unlike the dom-legacy config this isn't using a dynamic flag for determining whether it is unhydrated markup.
These prevent mistakes when a component is expected to be hydrated.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Comparing: e02baf6...8b8c255 Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: Expand to show |
Otherwise we end up throwing since the Fizz implementation doesn't have one, or if it did, we'd fail the test since it was enabled.
Follow up to #30105. This supports `renderToMarkup` in a non-RSC environment (not the `react-server` condition). This is just a Fizz renderer but it errors at runtime when you use state, effects or event handlers that would require hydration - like the RSC version would. (Except RSC can give early errors too.) To do this I have to move the `react-html` builds to a new `markup` dimension out of the `dom-legacy` dimension so that we can configure this differently from `renderToString`/`renderToStaticMarkup`. Eventually that dimension can go away though if deprecated. That also helps us avoid dynamic configuration and we can just compile in the right configuration so the split helps anyway. One consideration is that if a compiler strips out useEffects or inlines initial state from useState, then it would not get called an the error wouldn't happen. Therefore to preserve semantics, a compiler would need to inject some call that can check the current renderer and whether it should throw. There is an argument that it could be useful to not error for these because it's possible to write components that works with SSR but are just optionally hydrated. However, there's also an argument that doing that silently is too easy to lead to mistakes and it's better to error - especially for the e-mail use case where you can't take it back but you can replay a queue that had failures. There are other ways to conditionally branch components intentionally. Besides if you want it to be silent you can still use renderToString (or better yet renderToReadableStream). The primary mechanism is the RSC environment and the client-environment is really the secondary one that's only there to support legacy environments. So this also ensures parity with the primary environment. DiffTrain build for commit 1e241f9.
Stacked on top of #30121. This is the same thing we do for `renderToReadableStream` so that you don't have to manually inject it into the stream. The only reason we didn't for `renderToString` / `renderToStaticMarkup` was to preserve legacy behavior but since this is a new API we can change that. If you're rendering a partial it doesn't matter. This is likely what you'd do for RSS feeds. The question is if you can reliably rely on the doctype being used while rendering e-mails since many clients are so quirky. However, if you're careful it also doesn't hurt so it seems best to include it.
); | ||
}); | ||
|
||
// @gate disableClientCache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It took me a while to figure out that disableClientCache is hard coded in the test flags and not derived from other flags. Couldn't figure out why it was only failing one config.
Follow up to #30105.
This supports
renderToMarkup
in a non-RSC environment (not thereact-server
condition).This is just a Fizz renderer but it errors at runtime when you use state, effects or event handlers that would require hydration - like the RSC version would. (Except RSC can give early errors too.)
To do this I have to move the
react-html
builds to a newmarkup
dimension out of thedom-legacy
dimension so that we can configure this differently fromrenderToString
/renderToStaticMarkup
. Eventually that dimension can go away though if deprecated. That also helps us avoid dynamic configuration and we can just compile in the right configuration so the split helps anyway.One consideration is that if a compiler strips out useEffects or inlines initial state from useState, then it would not get called an the error wouldn't happen. Therefore to preserve semantics, a compiler would need to inject some call that can check the current renderer and whether it should throw.
There is an argument that it could be useful to not error for these because it's possible to write components that works with SSR but are just optionally hydrated. However, there's also an argument that doing that silently is too easy to lead to mistakes and it's better to error - especially for the e-mail use case where you can't take it back but you can replay a queue that had failures. There are other ways to conditionally branch components intentionally. Besides if you want it to be silent you can still use renderToString (or better yet renderToReadableStream).
The primary mechanism is the RSC environment and the client-environment is really the secondary one that's only there to support legacy environments. So this also ensures parity with the primary environment.