I'm working on a React form. The web component part works fine, but as shown in the example, I'm having issues updating properties in the App component, when attributes are updated async later.
code example: https://stackblitz.com/edit/react-ts-nypnbz?file=index.tsx
What am I missing to get the token value sent to when its updated async as demonstrated by the setTimeout on the host page?
A few things I haven't played with before but this works.
import React, { useState } from "react";
import { render } from "react-dom";
interface AppProps {
name: string | null;
token: string | null;
}
const App = ({ name, token }: AppProps) =>
token ? (
<span>
{name} has token {token}
</span>
) : (
<span>{name} has no token</span>
);
class SignupForm extends HTMLElement {
setToken;
FormApp = (props: AppProps) => {
const [token, updateToken] = useState("");
this.setToken = updateToken;
return <App name={props.name} token={token} />;
};
connectedCallback() {
const mountPoint = document.createElement("div");
this.attachShadow({ mode: "open" }).appendChild(mountPoint);
render(<this.FormApp name={this.name} token={this.token} />, mountPoint);
}
get name() {
return this.getAttribute("name");
}
get token() {
return this.getAttribute("token");
}
static get observedAttributes() {
return ["name", "token"];
}
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
console.log(
`${name}'s value has been changed from ${oldValue} to ${newValue}`
);
if (typeof this.setToken === "function") {
this.setToken(newValue);
}
}
}
if (!customElements.get("signup-form")) {
customElements.define("signup-form", SignupForm);
}