-
Notifications
You must be signed in to change notification settings - Fork 2
/
react.tsx
57 lines (50 loc) · 1.7 KB
/
react.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import React from 'react';
import PDomClass from '.';
class PDomReact extends PDomClass {
protected framework = 'react';
protected frameworkVersion = React.version;
public setProps(props) {
this.sendMessage({
_type: 'pdom-props',
props,
});
}
}
function PDom<T extends React.ComponentType<any>>(importFn: () => Promise<{ default: T }>): T {
const Component = React.lazy(importFn);
return React.forwardRef<React.ComponentProps<typeof Component>>((props, ref) => {
const containerRef = React.useRef(null);
const _ref = React.useRef(null);
const pDomRef = ref ?? _ref;
React.useEffect(() => {
const pDom = new PDomReact(containerRef.current, {
scripts: [
importFn,
],
domainUrl: 'https://react.pdom.dev'
});
pDom.render()
pDomRef.current = pDom;
pDom.onMessage((message) => {
if (message._type === 'pdom-callback') {
const { callbackId, args } = message;
return props[callbackId](...args);
}
});
}, []);
React.useEffect(() => {
const newProps = {};
for (const key in props) {
const value = props[key];
if (typeof value === 'function') {
newProps[key] = '__function__';
} else {
newProps[key] = value;
}
}
pDomRef.current?.setProps?.(newProps);
}, [props]);
return <div ref={containerRef} className="pdom"></div>
});
}
export default PDom;