-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
Handling different client and server content - not showing initial render #6190
Comments
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Hi there As of now, nobody has been assigned to the task yet. I made an attempt to address the issue today. It appears that the playground is being statically rendered. When examining the page source, it shows that the initial page sent contains "is Client". To resolve this, I explored methods to force dynamic rendering and discovered that we can utilize the following export statement: and changed the SandPack component code to the following: <!--
HTML content inside <div id="root">...</div>
was generated from App by react-dom/server.
-->
<div id="root"><h1>Is Server</h1></div> import './styles.css';
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';
hydrateRoot(document.getElementById('root'), <App />); export const dynamic = 'force-dynamic';
import { useState, useEffect } from "react";
export default function App() {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
return (
<h1>
{isClient ? 'Is Client' : 'Is Server'}
</h1>
);
} Let me know if you have any suggestions or if I should proceed with additional debugging to fix the problem. |
It seems that the component is client side rendering from the start. If I fully understand the issue, it's supposed to display is server when the component first mounts then the useEffect runs to re-render the component showing is client, but instead it shows only is client, right? |
I think the issue is as soon as the server render is shown the isClient is set to true. So the change happens instantly and we cant't see the isServer text |
i fixed the bug in above commit #6216 by adding a 1 second timeout for changing the isClient state now the transition between isServer to isClient text is distinguishable |
@Ahmed-Abou-Emran I think It is an iframe issue, the purpose of that demo is to prevent mismatch between the content on the server and the client. @joeljtomy indeed, adding an additional one second delay should fix the issue. |
I am seeing this work on the forked sandbox, but it should work on the site. I don't like the timeout solution because the code should show an example of how it works in practice and you would never add a timeout for hydrateRoot. But if we wanted to pause it and call hydration afterwards, we could add a button and text like "This is the server rendered HTML before hydrateRoot is called" and a button to hydrate which calls hydrate root. I would also include a code comment that says not to call it in a button in a real app. |
In the hydrateRoot page, it is mentioned that
"This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration."
which means that the initial render on the playground should show "Is Server", but it shows directly "Is Client" which is very confusing for learners and doesn't show the real behavior.
I tired opening the sandbox in external window, and it indeed shows "Is Server" first and then changing to "Is Client" as expected.
In the Website:
In The sandbox (using the fork button):
The text was updated successfully, but these errors were encountered: