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

paltform-browser's render function could handle entire document #44

Closed
Coachonko opened this issue Apr 3, 2024 · 7 comments
Closed
Labels
enhancement New feature or request

Comments

@Coachonko
Copy link

Coachonko commented Apr 3, 2024

paltform-browser's render function rejects document as parameter because document instanceof Element evaluates to false.
A few small changes should allow the render function to correctly handle the entire document as root.

@atellmer
Copy link
Owner

atellmer commented Apr 3, 2024

I just wrote in the next issue why document is not supported. Because besides our application, there are other sources that can influence the DOM and we do not control these sources.

@atellmer
Copy link
Owner

atellmer commented Apr 3, 2024

I mean something like that.
1
These are unpredictable DOM elements that are introduced by browser extensions. And we will inevitably get mismatch errors if we compare the actual DOM tree and the Fiber tree.

@Coachonko
Copy link
Author

Coachonko commented Apr 3, 2024

I just wrote in the next issue why document is not supported. Because besides our application, there are other sources that can influence the DOM and we do not control these sources.

This is a very good point.
I have quickly investigated how React handles this issue because I never encountered it myself while using React. It turns out React doesn't seem handle it either on 18.2 release, as described in this open issue. But it seems a solution was pushed to 18.3 (still investigating)

I think a possible solution to this problem, besides the workaround shown in the dark docs, would probably be to mark server-rendered elements with adjacent comments (inspired by qwik), or with element attributes, and make the hydration process ignore non-marked elements.

@atellmer
Copy link
Owner

atellmer commented Apr 3, 2024

It seems to me that a good solution is one that does not require writing any code and still works flawlessly. I came to this solution: splitting the code into Page (root HTML) and App. In this case, the App is inserted into a Page of type

<Page>
  <App />
</Page>

As a result, we get full SSR generation, but at the same time we hydrate only the App. An example is here

@Coachonko
Copy link
Author

It seems to me that a good solution is one that does not require writing any code and still works flawlessly. I came to this solution: splitting the code into Page (root HTML) and App. In this case, the App is inserted into a Page of type

<Page>
  <App />
</Page>

As a result, we get full SSR generation, but at the same time we hydrate only the App. An example is here

Yes indeed this technique works perfectly. But if hydrateRoot can accept the whole document, without adding comments/attributes and adding more complexity to the hydration process, it would be nice.

@atellmer
Copy link
Owner

atellmer commented Apr 3, 2024

For me, this problem can only lie in the plane of beauty, but not functionality. Yes, it would be nice to be able to work with document, although from a practical point of view this would entail the problems described above. If we can fix this by refactoring some of the code, then that will be good. However, if this implementation requires writing complex logic, then this intervention does not seem necessary, because we will simply increase the complexity of the system, while solving a problem for which there is already a solution.

@atellmer
Copy link
Owner

atellmer commented Apr 4, 2024

I added this

import { h, component, useState } from '@dark-engine/core';
import { hydrateRoot } from '@dark-engine/platform-browser';

const App = component(() => {
  const [count, setCount] = useState(0);

  return (
    <html lang='en'>
      <head>
        <meta charset='UTF-8' />
        <meta name='viewport' content='width=device-width, initial-scale=1.0' />
        <meta http-equiv='X-UA-Compatible' content='ie=edge' />
        <title>Test: {count}</title>
      </head>
      <body>
        <div id='root'>
          <div>{count}</div>
          <button onClick={() => setCount(x => x + 1)}>click</button>
        </div>
        <script src='./build.js' defer></script>
      </body>
    </html>
  );
});

hydrateRoot(document, <App />);

Looks very strange 🙃

@atellmer atellmer closed this as completed Apr 5, 2024
@atellmer atellmer added the enhancement New feature or request label Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants