React and Vue strip attributes
I'm trying to understand how React and Vue can report 100% compatibility. Here's an example of a simple Hello World web component that works fine in vanilla web apps and in web apps that use Solid or Svelte, but will not work with React or Vue.
class HelloWorld extends HTMLElement {
name = "";
constructor() {
super();
this.attachShadow({ mode: "open" });
}
connectedCallback() {
this.name = this.getAttribute("name") || "World";
this.render();
}
render() {
const { shadowRoot } = this;
if (shadowRoot) shadowRoot.innerHTML = `<p>Hello, ${this.name}!</p>`;
}
}
if (!customElements.get("hello-world")) {
customElements.define("hello-world", HelloWorld);
}
An example of using this custom element is <hello-world name="Sam"></hello-world>.
The problem is that when React and Vue see that the web component has a property with the same name as an attribute, they set the property to the attribute value and delete the attribute. When connectedCallback is called and that attempts to get the attribute value, null is returned. The web component could be modified to handle the case of the property already being set, but that feels wrong because it's a change that is only needed for compatibility with React and Vue.
Should React and Vue practice of removing attributes be considered wrong?
I'm trying to understand how React and Vue can report 100% compatibility.
Yeah, definitely. The tests are not covering everything they need to cover.
This issue is a subset of this meta issue:
- https://github.com/webcomponents/custom-elements-everywhere/issues/2352
That issue will test that we have 100% control over the values we can pass directly for DOM. For now I made a manual test and published those results.
The work @mrginglymus is doing to simplify the test setup will make it much easier to add new tests in a more manageable way:
- https://github.com/webcomponents/custom-elements-everywhere/pull/2552