-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender-external.jsx
More file actions
44 lines (33 loc) · 1.29 KB
/
render-external.jsx
File metadata and controls
44 lines (33 loc) · 1.29 KB
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
import React, { useEffect, useRef } from "react";
import { createRoot } from "react-dom/client";
import {ErrorBoundary} from './error-boundary.jsx';
import {data_pointer} from './helpers.jsx';
export function RenderExternal({className='', component: Comp, payload={}}) {
if ( ! Comp ) {
return null;
}
const reff = useRef();
const is_internal = Comp.length!==2; // 2 means it is from external script.
useEffect(()=>{
// If not internal componenet, call the function, so it can render their contents.
if ( ! is_internal && reff?.current) {
Comp(reff.current, payload);
}
}, [payload]);
// If internal component, then simply embed as usual. External component can only be called as function through useEffect hook.
return is_internal ?
<ErrorBoundary>
<Comp className={className} {...payload}/>
</ErrorBoundary>
:
<div ref={reff} className={className}></div>
}
export function mountExternal( id, el, component) {
const {mountpoints={}} = window[data_pointer];
const current_session = el.getAttribute('data-react-materials-mountpoint') === id;
el.setAttribute('data-react-materials-mountpoint', id);
if ( ! current_session || ! mountpoints[id] ) {
window[data_pointer].mountpoints[id] = createRoot(el);
}
window[data_pointer].mountpoints[id].render(component);
}