React.lazy only works with default exports. This error occurs when you try to lazy-load a component that uses named exports instead. Learn how to fix this by using Promise chaining or creating an intermediate module.
React.lazy() is a React function that enables code-splitting by lazy-loading components. It expects the imported module to have a default export containing a valid React component. When you try to lazy-load a component that uses named exports (export const MyComponent = ...) instead of a default export (export default MyComponent), React.lazy cannot find the component and throws this error. This is a limitation of React.lazy itself—it currently doesn't support named exports directly. The module must resolve to an object with a .default property that contains the React component.
Check that your component file has export default at the top level:
// Correct - default export
export default function MyComponent() {
return <div>Hello</div>;
}
// Wrong - named export
export const MyComponent = () => {
return <div>Hello</div>;
};If your component uses named exports, modify your React.lazy call to chain the import Promise and provide a default export:
import { lazy, Suspense } from 'react';
// Wrap named export in default for React.lazy
const MyComponent = lazy(() =>
import('./MyComponent').then(module => ({
default: module.MyComponent
}))
);
// Use with Suspense
export default function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}Create a wrapper file that re-exports the named export as default:
MyComponent.jsx (original file with named export)
export const MyComponent = () => {
return <div>Hello</div>;
};MyComponentLazy.jsx (new wrapper)
export { MyComponent as default } from './MyComponent';App.jsx (use the wrapper)
import { lazy, Suspense } from 'react';
const MyComponent = lazy(() => import('./MyComponentLazy'));
export default function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}Always wrap lazy components in a Suspense boundary with a fallback UI:
import { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
export default function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}The fallback will display while the component is being loaded.
For TypeScript projects, the Promise chaining approach works seamlessly. The intermediate module approach is cleaner if you're using multiple lazy imports from the same named export file. Consider your project structure when choosing between the two solutions.
If you're using React Router or Next.js, they may provide their own code-splitting utilities that support named exports. Check your framework's documentation for alternatives to React.lazy.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite