LazyMount.tsx 772 B

1234567891011121314151617181920
  1. import { Suspense, useEffect, useState, type ReactNode } from 'react';
  2. interface LazyMountProps {
  3. when: boolean;
  4. fallback?: ReactNode;
  5. children: ReactNode;
  6. }
  7. // Mounts children only after `when` first becomes true and keeps them mounted
  8. // thereafter, so React.lazy modals get loaded on demand but their close
  9. // animations still play out. Pair with `lazy(() => import(...))` modal imports
  10. // on heavy list pages to keep the initial bundle small.
  11. export default function LazyMount({ when, fallback = null, children }: LazyMountProps) {
  12. const [mounted, setMounted] = useState(when);
  13. useEffect(() => {
  14. if (when && !mounted) setMounted(true);
  15. }, [when, mounted]);
  16. if (!mounted) return null;
  17. return <Suspense fallback={fallback}>{children}</Suspense>;
  18. }