Skip to content

Commit 954ceeb

Browse files
committed
Fix: ensuring we don't rerender while awaiting a root
1 parent 18421b6 commit 954ceeb

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

src/ReactHTMLElement.ts

+16
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,24 @@ import { getCreateRoot } from './react-dom-client';
55
type Renderable = Parameters<ReactDOM.Renderer>[0][number];
66
type ReactHTMLElementDOMRoot = Pick<Root, 'render' | 'unmount'>;
77

8+
const awaitValue = <T>(awaiter: () => T): Promise<T> => new Promise((resolve) => {
9+
const result = awaiter();
10+
if (result) {
11+
resolve(result);
12+
} else {
13+
setTimeout(() => resolve(awaitValue(awaiter)), 100);
14+
}
15+
});
16+
817
class ReactHTMLElement extends HTMLElement {
918
private _initialized?: boolean;
1019

1120
private _mountPoint?: Element;
1221

1322
private _root?: ReactHTMLElementDOMRoot;
1423

24+
private _awaitingRoot = false;
25+
1526
private getShadowRoot(): ShadowRoot {
1627
return this.shadowRoot || this.attachShadow({ mode: 'open' });
1728
}
@@ -43,9 +54,14 @@ class ReactHTMLElement extends HTMLElement {
4354
}
4455

4556
async root(): Promise<ReactHTMLElementDOMRoot> {
57+
if (this._awaitingRoot) {
58+
await awaitValue(() => this._root);
59+
}
4660
if (this._root) return this._root;
4761

62+
this._awaitingRoot = true;
4863
this._root = (await getCreateRoot())(this.mountPoint);
64+
this._awaitingRoot = false;
4965
return this._root;
5066
}
5167

0 commit comments

Comments
 (0)