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 Component's constructor is not called when custom element is created via document.createElement #68

Open
lpommers opened this issue Feb 23, 2022 · 1 comment

Comments

@lpommers
Copy link

lpommers commented Feb 23, 2022

This is documented here in this comment from another PR: #64 (comment). document.createElement should run the component's constructor method.

class CounterPreact extends Component {
  constructor() {
    super()
    console.log('here')
  }
}

register(CounterPreact, 'x-counter-preact')

// ...

document.createElement('x-counter-preact') // no output
class CounterPlain extends HTMLElement {
  constructor() {
    super()
    console.log('here')
  }
}

customElements.define('x-counter-plain', CounterPlain)

// ...

document.createElement('x-counter-plain') // outputs here

The constructor only seems to fire when the custom element as appended to the DOM.

@mikerob215
Copy link

I was curious about this behavior and looked into it a little bit. The reason is that making an instance of the web component does not make an instance of the preact component. That only happens when the preact component is rendered the first time, and the earliest that can happen is in the connectedCallback which runs when the element is appended. Its technically possible to render the preact component in the constructor but it would only work if also using the shadow dom as attaching the shadow creates a document fragment. Without a shadow root, the constructor doesn't have access to any dom yet and its unsafe to call render.

Heres a codesandbox to demonstrate: https://codesandbox.io/s/tender-shamir-dwk4zb?file=/src/index.js

It creates a preact component that logs in the constructor, and manually wraps it in 2 web components, one with a shadow root and one without. Both web components will console.log when calling document.createElement, but the one without the shadow root will cause an error.

So I think current behavior makes sense, but curious about any scenarios where you'd want both constructors to run at the same time.

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

2 participants