Skip to content

Commit

Permalink
Fix: ensuring we don't rerender while awaiting a root
Browse files Browse the repository at this point in the history
  • Loading branch information
stevematney committed Jan 10, 2023
1 parent 18421b6 commit 954ceeb
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/ReactHTMLElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,24 @@ import { getCreateRoot } from './react-dom-client';
type Renderable = Parameters<ReactDOM.Renderer>[0][number];
type ReactHTMLElementDOMRoot = Pick<Root, 'render' | 'unmount'>;

const awaitValue = <T>(awaiter: () => T): Promise<T> => new Promise((resolve) => {
const result = awaiter();
if (result) {
resolve(result);
} else {
setTimeout(() => resolve(awaitValue(awaiter)), 100);
}
});

class ReactHTMLElement extends HTMLElement {
private _initialized?: boolean;

private _mountPoint?: Element;

private _root?: ReactHTMLElementDOMRoot;

private _awaitingRoot = false;

private getShadowRoot(): ShadowRoot {
return this.shadowRoot || this.attachShadow({ mode: 'open' });
}
Expand Down Expand Up @@ -43,9 +54,14 @@ class ReactHTMLElement extends HTMLElement {
}

async root(): Promise<ReactHTMLElementDOMRoot> {
if (this._awaitingRoot) {
await awaitValue(() => this._root);
}
if (this._root) return this._root;

this._awaitingRoot = true;
this._root = (await getCreateRoot())(this.mountPoint);
this._awaitingRoot = false;
return this._root;
}

Expand Down

0 comments on commit 954ceeb

Please sign in to comment.