Skip to content
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

React CM Mode (18) stacking app during hydrateRoot #21985

Open
maraisr opened this issue Jul 29, 2021 · 13 comments
Open

React CM Mode (18) stacking app during hydrateRoot #21985

maraisr opened this issue Jul 29, 2021 · 13 comments
Labels
React 18 Bug reports, questions, and general feedback about React 18 Type: Discussion

Comments

@maraisr
Copy link

maraisr commented Jul 29, 2021

React version: 18.0.0-alpha-9f88b5355-20210728

Steps To Reproduce

See repo https://github.com/maraisr/react-suspense-repro

Link to code example:

https://github.com/maraisr/react-suspense-repro

The current behavior

react hydrateRoot is stacking dom trees

will note here that Suspense obviously isnt needed that as nothing is async. I can illustrate here as well if you require a demo with the Suspense needing to do something??

The expected behavior

react hydrateRoot to not stack dom trees

@maraisr maraisr added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Jul 29, 2021
@eps1lon
Copy link
Collaborator

eps1lon commented Jul 29, 2021

Thanks for the feedback.

On the server you're just rendering <App /> (https://github.com/maraisr/react-suspense-repro/blob/main/server.jsx#L24) but on the client you're hydrating a different tree: <Suspense><App /></Suspense> (https://github.com/maraisr/react-suspense-repro/blob/4278aaa9d165a5394e70393f534347210a18c245/client.jsx#L12-L19).

This behavior isn't supported in React 16 as well. However, it is currently silently processed for historic reasons: #16943

Though it may make sense to re-introduce a warning in React 18.

@eps1lon eps1lon added React 18 Bug reports, questions, and general feedback about React 18 Type: Discussion and removed Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug labels Jul 29, 2021
@maraisr
Copy link
Author

maraisr commented Jul 29, 2021

the HTML trees is 100% identical, as Suspense on the server would do nothing? I can see there is a test for it here (https://github.com/facebook/react/blob/main/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js#L417) perhaps the error is just lost?

All im saying above is, the fibre trees arent flushed to the client?? so as far as client is concerned the html is correct? As the net result is, the DOM does in fact equal the fibre tree, and thus should have hydrated?? Or is there anything fancy going on to tell the client about a suspense boundary?

So I understand, youre saying what im seeing in that repro is 100% normal, and 100% okay? And the fix is it put Suspense on the server as well?

@eps1lon
Copy link
Collaborator

eps1lon commented Jul 29, 2021

the HTML trees is 100% identical, as Suspense on the server would do nothing?

HTML is not the important part here. The component trees should be the same.

Suspense on the server does something. It instructs React how it should orchestrate hydration on the client (e.g. prioritazion). reactwg/react-18#37 goes into more detail about how Suspense works on the server and affects hydration.

So I understand, youre saying what im seeing in that repro is 100% normal, and 100% okay? And the fix is it put Suspense on the server as well?

These are quite loaded terms so I wouldn't use them. I would usually say that the behavior for hydration mismatches is undefined.

Personally, I would prefer a warning but this might be problematic as per #16943

But it should be fixed with the same tree on the server (error boundary as well) from what I can tell.

@theKashey
Copy link
Contributor

So the only way to “use” Suspense on the client after 16.10 is to provide a null fallback, ensuring that nothing will suspend during the initial hydration(ie matching server behaviour), allowing such operations only later.

This is working for 16 and 17, but not for 18 or just for CM. @maraisr can you clarify what constrain - react version or rendering mode - is causing double render?

@maraisr
Copy link
Author

maraisr commented Jul 29, 2021

Suspense on the server does something. It instructs React how it should orchestrate hydration on the client (e.g. prioritazion). reactwg/react-18#37 goes into more detail about how Suspense works on the server and affects hydration.

Ah yeah i see;

<html><body><div id="app"><!--$--><h1>Hello, world!</h1><!--/$--></div><script src="/assets/client.js"></script></body></html>

There is special $ markings in the html for this. So does this mean that in 18, Suspense do occupy html nodes now as well albeit comments?

@eps1lon
Copy link
Collaborator

eps1lon commented Jul 29, 2021

So does this mean that in 18, Suspense do occupy html nodes now as well albeit comments?

I think this is just an implementation detail that you shouldn't need to worry about. As long as you use the appropriate server rendering API and client side API and make sure the trees are the same, everything should work.

@maraisr
Copy link
Author

maraisr commented Jul 29, 2021

As long as you use the appropriate server rendering API and client side API and make sure the trees are the same, everything should work.

From my repo above, is the apis appropriate? Simply just trees not being the same being the issue? Can close this if that's the case? (Maybe just throw some errors in client??)

@eps1lon
Copy link
Collaborator

eps1lon commented Jul 29, 2021

From my repo above, is the apis appropriate?

Yep 👍🏻

Can close this if that's the case? (Maybe just throw some errors in client??)

I would still like to get some input from a core member whether we still want to silently fail in React 18 or if we should add a dev-only warning similar to how we warn on hydration mismatches for HTML.

@maraisr
Copy link
Author

maraisr commented Jul 29, 2021

Ya probably not the best thingy to stack dom in any case 😅

@sebmarkbage
Copy link
Collaborator

There should be a hydration error in dev mode. Is that not the case? If so that’s a bug.

It’s not a bug that it stacks the DOM node. It’s an unfortunate consequence of us needing some way to inject script tags and other extra nodes that might end up in the root as extra nodes. Currently the plan is to just live with it because it’s such an obvious error and only happens directly at the root so once you fix it, it doesn’t happen again.

@eps1lon
Copy link
Collaborator

eps1lon commented Jul 29, 2021

There should be a hydration error in dev mode. Is that not the case? If so that’s a bug.

Seeing no error message when using hydrateRoot: https://codesandbox.io/s/jovial-cherry-2qxn3?file=/src/index.js

Looks like

it('Suspense + hydration in legacy mode (at root)', () => {
const element = document.createElement('div');
element.innerHTML = '<div>Hello World</div>';
const div = element.firstChild;
const ref = React.createRef();
ReactDOM.hydrate(
<React.Suspense fallback={null}>
<div ref={ref}>Hello World</div>
</React.Suspense>,
element,
);
// The content should've been client rendered.
expect(ref.current).not.toBe(div);
// Unfortunately, since we don't delete the tail at the root, a duplicate will remain.
expect(element.innerHTML).toBe(
'<div>Hello World</div><div>Hello World</div>',
);
});
is already covering the current behavior but does not include assertions about console errors.

@maraisr
Copy link
Author

maraisr commented Jul 29, 2021

Is that not the case? If so that’s a bug

Yup there's no error or messaging in either mode.

I guess that's why I originally thought there's a bug with React. But guess the bug in the end is just no messaging 😅

Thanks for giving this issue the time of day tho folk ❤️

@gaearon
Copy link
Collaborator

gaearon commented Mar 25, 2022

There is an error message in 18 RC.
https://codesandbox.io/s/eloquent-cherry-iwt1zz?file=/src/index.js

Though it's not super descriptive about where the error happens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
React 18 Bug reports, questions, and general feedback about React 18 Type: Discussion
Projects
None yet
Development

No branches or pull requests

5 participants