Skip to content

Instantly share code, notes, and snippets.

@develohpanda
Last active March 19, 2024 03:19
Show Gist options
  • Save develohpanda/fc77eda88f65250183e74b6f809f9c8c to your computer and use it in GitHub Desktop.
Save develohpanda/fc77eda88f65250183e74b6f809f9c8c to your computer and use it in GitHub Desktop.
SSR React Utilities
// Used like <LazyLoadClientOnly loader={() => import('/foo')} bar="baz" /> where `bar` is a prop of the `Foo` component.
import {
ComponentProps,
ComponentType,
LazyExoticComponent,
ReactNode,
Suspense,
lazy,
useEffect,
useRef,
useState,
} from 'react';
type Props<T extends ComponentType<unknown>> = {
loader: Parameters<typeof lazy<T>>['0'];
fallback?: ReactNode;
};
export const LazyLoadClientOnly = <T extends ComponentType<unknown>>({
loader,
fallback,
...props
}: Props<T> & Omit<ComponentProps<T>, keyof Props<T>>) => {
const [Component, setComponent] =
useState<LazyExoticComponent<ComponentType<unknown>>>();
// Using a ref to make sure the prop updating does not result in another lazy import
const loaderRef = useRef(loader);
useEffect(() => {
setComponent(() => lazy(loaderRef.current));
}, []);
return (
<Suspense fallback={fallback}>
{Component ? <Component {...props} /> : fallback}
</Suspense>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment