Last active
May 31, 2023 02:14
-
-
Save finas/cec634cbd0a1d955075fbb6f7a3c6d14 to your computer and use it in GitHub Desktop.
Load remote bundled react component.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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