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

Preact + Custom Element Side Effects #39

Closed
c58 opened this issue Feb 5, 2016 · 17 comments
Closed

Preact + Custom Element Side Effects #39

c58 opened this issue Feb 5, 2016 · 17 comments

Comments

@c58
Copy link

c58 commented Feb 5, 2016

Hi!
I'm trying to use Preact as React replacement in my mobile app. But it seems that Preact does not support Web Components used inside "render". Web Components is used from OnsenUI framework.

I think that i know why it does not work. Preact uses vdom-dom diffing algorithm, React uses vdom-vdom. Onsen's web components changes a DOM (trying to change) and Preact is thinking that it is not right and it's deny it.

Is there any solution with Preact?
Thanks.

@developit
Copy link
Member

@c58 - very interesting. Have you tried this with the beta version? (Currently 3.0.1)

To help me investigate, what are you seeing happen - for example: do the web components get instantiated, but their attributes are not set?

Thanks!

@c58
Copy link
Author

c58 commented Feb 5, 2016

@developit unfortunately, 3.0.1 does not work too.
I've made an example to test it out.
https://github.com/c58/preact-webcomp-test

In src/index.js just uncomment Preact part and comment React part and see the difference.

@developit
Copy link
Member

Perfect, will take a look. Will be interesting to see if this is related to Shadow DOM polyfills.

@c58
Copy link
Author

c58 commented Feb 5, 2016

@developit i've fixed minor mistake in the example. The issue is still there.

@developit
Copy link
Member

It looks like the way Onsen instantiates CustomElements.js (from the Polymer project) is causing it not to use Shadow DOM at all. This means things like <ons-page> moves all of its children into a different parent element, which seems like the kind of things Preact can't really account for. I'm doing some testing to see how React can do the initial render without issue here, but I think a subsequent re-render would still mess things up for either framework. Will get back to you shortly.

@c58
Copy link
Author

c58 commented Feb 5, 2016

The same thing happened with mithril. About re-rendering: with react no issues at all. I have tried to change a content in ons-page and ons-toolbar – content re-rendered as expected.

5 февр. 2016 г., в 18:14, Jason Miller notifications@github.com написал(а):

It looks like the way Onsen instantiates CustomElements.js (from the Polymer project) is causing it not to use Shadow DOM at all. This means things like moves all of its children into a different parent element, which seems like the kind of things Preact can't really account for. I'm doing some testing to see how React can do the initial render without issue here, but I think a subsequent re-render would still mess things up for either framework. Will get back to you shortly.


Reply to this email directly or view it on GitHub.

@developit
Copy link
Member

@c58 I came up with a test that shows that React behaves the same way after initial render. The reason Preact and Mithril both remove ons's elements on initial render is because they build the DOM imperatively, whereas React initially uses a static HTML snapshot inserted via innerHTML to do so.

However, this means that changing the structure of the DOM using React will still cause issues.

Really this boils down to what Preact (and React) are designed for: they are designed to constantly morph the DOM into a known state. You simply specify the desired DOM structure, and the work of mutating the DOM to look correctly is done for you.

I've published my React example to a fork for you to look at, it shows that after 1s a DOM structure change within <ons-page> causes the same degradation visible via Preact & Mithril.

I'm definitely still open to working on this, but I think the issue here is a lot more specific than Web Components: It's specifically integrating VDOM libraries with code that expects to be able to destructively mutate the DOM.

You can see a fairly complex example of how to account for this if you view the source of preact-mdl. Essentially, there is a wrapper placed around render() that tries to "backport" outside DOM mutations into the VDOM structure in order to preserve them. However, I have not yet found a good way to account for "injected" layers using this technique - where children appended to an element are forcibly moved into a different parent outside the control of Preact.

@developit developit changed the title Using Preact with Web Components Preact + Custom Elements + Side Effects Feb 6, 2016
@developit developit changed the title Preact + Custom Elements + Side Effects Preact + Custom Element Side Effects Feb 6, 2016
@c58
Copy link
Author

c58 commented Feb 6, 2016

Yes, you are right, it does not work :(
I will create an issue in OnsenUI repository.

UPDATE:
I think it is already exists
OnsenUI/OnsenUI#985

@developit
Copy link
Member

On the positive side, thanks for letting me know about Onsen :)

I'm testing out Polymer + Preact as well to see if there are issues.

@developit
Copy link
Member

Closing for now, will revisit.

@tconroy
Copy link

tconroy commented Apr 3, 2017

Hey there,
I'm running into an issue with a custom WebComponent not working when React is swapped for preact-compat. It seems to render on the initial view, but not subsequent views (IE, first page in a SPA app works, second page does not). Was there ever any workaround or resolution to this?

running

    "preact": "7.2.0",
    "preact-compat": "3.14.1",

@developit
Copy link
Member

Hi @tconroy - would you be able to open a new issue in the preact-compat repo with a few details of your setup? It doesn't seem related to this issue, since side effects have been fully supported in Preact since 6.x.

@tconroy
Copy link

tconroy commented Apr 3, 2017

@developit Sure thing. Apologies, I should have posted there first. Hoping to get this resolved :)

@H-Plus-Time
Copy link

Looks like the 'renders once, subsequent renders don't work' issue remains whether or not preact-compat is present :-S. I'm running:

    "preact": "8.1.0",
    "preact-router": "2.4.1",
    "wc-loader": "1.1.3"

After switching routes, the element (paper-input, vaadin-grid in this case) is still there in DOM (all attributes intact), but shady DOM is toast (as to why my setup defaults to shady dom despite browser support... ¯_(ツ)_/¯ ).

@tconroy
Copy link

tconroy commented May 9, 2017

@H-Plus-Time I'm having a similar experience. FWIW my components are using the v1 spec ( not v0 ).

@developit -- is there any info I/we can provide to make debugging this easier/simpler?

@developit
Copy link
Member

this might come down to removing component recycling, which is already likely to happen for other reasons. preact just creates DOM elements via createElement(), there's no special behavior for WC's so there isn't really a place to workaround. I'll try to ping you when I have something published without component recycling.

@tconroy
Copy link

tconroy commented May 17, 2017

Sounds good @developit! I have a strong feeling that that is the issue -- although unfortunately my knowledge of web components is a bit limited.

If you would like me to test out a pre-release version to see if it fixes the issue on my end toss me a message and I'd be more than happy to report my findings.

Cheers!

marvinhagemeister added a commit that referenced this issue Mar 2, 2019
marvinhagemeister pushed a commit that referenced this issue Mar 15, 2022
- Try to mimic the Preact TSD.

- Example usage with `noImplicitAny` enabled:

  import { render } from "preact-render-to-string";

- No idea if I've done it right but it seems to compile and hopefully
  someone more knowledgeable can build on this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants