-
-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent destroy/render the remote component every time re-rendering from the host #3478
Comments
Hi @ducdv-lumin, Thank you for reporting this issue and providing a minimal reproduction example. I have reproduced this issue and this pr releated seems not working, it's still rendered and destroyed every time the state changed. And I will take a look on how to solve this problem. Sorry for the late response because I've been kind of busy these days. I'll keep you updated on the progress. Thank you for your patience! |
Hi @danpeen Thank you for taking a look at my issue. Regarding my fixing PR, I'm not sure why it doesn't work for you. But anyway, I tried creating a minimal version of the type LazyModuleFederationProps = {
loading: React.ReactNode;
loader: () => Promise<DefaultComponent<unknown>>;
};
type ModuleHandlers = {
render(props: { dom: HTMLDivElement }): void;
destroy(props: { dom: HTMLDivElement }): void;
};
type ModuleProps = {
default(): ModuleHandlers;
};
const createLazyModuleFederation = ({ loader }: Pick<LazyModuleFederationProps, 'loader'>) =>
React.lazy(async () => {
const module = (await loader()) as unknown as ModuleProps;
return {
default: forwardRef((props: Record<string, unknown>, ref: Ref<HTMLDivElement>) => {
const rootRef =
ref && 'current' in ref
? (ref as React.MutableRefObject<HTMLDivElement | null>)
: useRef<HTMLDivElement | null>(null);
const renderDom = useRef<HTMLDivElement>(null);
const moduleRef = useRef<ModuleHandlers>(null);
useEffect(() => {
const renderTimeout = setTimeout(() => {
const moduleReturn = module.default();
moduleRef.current = moduleReturn;
renderDom.current = rootRef.current;
moduleReturn.render({ dom: rootRef.current, ...props });
});
return () => {
clearTimeout(renderTimeout);
setTimeout(() => {
moduleRef.current?.destroy?.({
dom: renderDom.current,
});
});
};
}, []);
return <div ref={rootRef} />;
}),
};
});
// All implemented codes as minimal version are referenced from these sources:
// - https://github.com/module-federation/core/blob/main/packages/bridge/bridge-react/src/create.tsx
// - https://github.com/module-federation/core/blob/main/packages/bridge/bridge-react/src/remote/index.tsx
export default function lazyModuleFederation<T>(info: LazyModuleFederationProps) {
return forwardRef((props: PropsWithoutRef<T>, ref: Ref<HTMLDivElement>) => {
const LazyComponent = useMemo(() => createLazyModuleFederation(info), []);
return (
<ErrorBoundary shouldRenderEmpty>
<React.Suspense fallback={info.loading}>
<LazyComponent {...props} ref={ref} />
</React.Suspense>
</ErrorBoundary>
);
});
} |
Hello @ducdv-lumin Thank you for your fixing code. Yesterday I have fixed it and can you try this version |
Hi @danpeen, thank you for the fix, that version works great for me! |
@ducdv-lumin OK, Thank you for validation. Then I'll submit a PR to address this. Thank you again! |
Describe the bug
When creating the remote component in the host using the
createRemoteComponent
function, every time I make a state change, the remote component flashes because it unmounts and mounts again. Here is a minimal example from the host, and I have ensured that the remote component from the remote repository works correctly without any issues.Used Package Manager
npm
System Info
Validations
The text was updated successfully, but these errors were encountered: