Skip to content

Instantly share code, notes, and snippets.

@finas
Last active May 31, 2023 02:14
Show Gist options
  • Save finas/cec634cbd0a1d955075fbb6f7a3c6d14 to your computer and use it in GitHub Desktop.
Save finas/cec634cbd0a1d955075fbb6f7a3c6d14 to your computer and use it in GitHub Desktop.
Load remote bundled react component.
import React from 'react';
export function useRemoteComponent<T>(url: string, componentName: string = 'RulesUI') {
const ref = React.useRef({
url: '',
component: null as unknown as React.FC<T>,
});
const [update, setUpdate] = React.useState(true);
React.useEffect(() => {
if (!url) {
return;
}
loadRemoteComponent(url).then((compnent) => {
ref.current.component = compnent;
ref.current.url = url;
setUpdate(!update);
});
}, [url]);
function loadRemoteComponent<T>(url: string) {
return fetch(url)
.then((res) => res.text())
.then((body) => {
const exports = {};
const globalThis = {
React,
};
let define = null
let module: any = undefined;
let require: any = (name: string) => {
if (name == 'React') return React;
}
try {
eval(body);
// @ts-ignore
return exports.default || globalThis[componentName];
} catch (e) {
console.error(e);
return Promise.reject();
}
});
}
return ref.current.component;
}
interface IRulesUI {
type?: RuleGroupType;
isDebugging?: boolean;
isReadonly?: boolean;
agentName?: string;
onSubmit?: (payload: IRuleGroup) => Promise<IRuleGroup>;
onChange?: (isChanged: boolean) => void;
}
export default function Demo() {
const type = 'autoApprove'
let RuleUIComponent: React.FC<IRulesUI> | null = null
RuleUIComponent = useRemoteComponent<IRulesUI>(`/api/get-module?type=${type}`)
const handleSubmit = (requestPayload) => {
// const note = window.prompt('Note', '')
// if (!note) {
// return Promise.reject()
// }
return fetch('/rma-csp/api/rule', {
method: 'put',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestPayload)
}).then(async res => {
if (res.status == 200) {
alert('updated !!')
return Promise.resolve(await res.json())
} else {
alert('failed --')
return Promise.reject(await res.json())
}
})
}
return <>
<div>
{
RuleUIComponent &&
<RuleUIComponent
isReadonly={false}
isDebugging={true}
agentName='Rubber duck'
type={type} onSubmit={handleSubmit} onChange={null} />
}
</div>
</>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment