Reputation: 1062
I'm trying to implement Route-based code splitting as mentioned in the React documentation.
Here's my app before adding lazy implementation. This works fine:
import Counter from "./Counter";
import Home from "./Home";
import Login from "./Login";
export function App() {
return (
<Router>
<Suspense fallback={<div>"Loading.."</div>}>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/counter" component={Counter} />
</Switch>
</Router>
);
}
All I changed is I replaced the 3 imports with this:
import { lazy, Suspense } from "react";
const Home = lazy(() => import("./Home"));
const Login = lazy(() => import("./Login"));
const Counter = lazy(() => import("./Counter"));
This code builds successfully but nothing renders on the browser and I get this error in console:
Uncaught undefined
The above error occurred in one of your React components:
in Unknown (created by Context.Consumer)
in Route (at App.tsx:29)
in Switch (at App.tsx:28)
in Suspense (at App.tsx:27)
in Router (created by BrowserRouter)
in BrowserRouter (at App.tsx:25)
in ErrorBoundary (at App.tsx:24)
in App (at src/index.tsx:19)
in Provider (at src/index.tsx:18)
in StrictMode (at src/index.tsx:17)
Am I doing something wrong?
Additional context:
If it matters, the components are named components re-exported as default because that's required by React.lazy:
export { Home as default } from "./Home";
And one of the components uses redux so the App is wrapped in a store provider:
<Provider store={store}>
<App />
</Provider>
Here's my tsconfig:
{
"compilerOptions": {
"baseUrl": ".",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"noFallthroughCasesInSwitch": true,
"target": "es5",
"module": "esnext"
},
"include": [
"src"
]
}
And package versions:
"react": "^17.0.1",
"react-dom": "^16.13.1",
"react-redux": "^7.2.1",
"react-scripts": "^4.0.1",
"react-router-dom": "^5.2.0",
"typescript": "^4.1.2",
Here's source code and possibly related issue on GitHub.
Upvotes: 16
Views: 7328
Reputation: 1
To solve the Uncaught undefined error while using lazy loading
upgrade your react and react-dom to same version >= 17.0.2
code should be similar to this
const Ecg = React.lazy(() => import('../ECG/Ecg'));
<Suspense fallback={<p>Loading...</p>}>
{
devicepage === "Ecg" ?
<Ecg val={egcvalue} devicecall={() => sendMsg('Ecg')}
devicecall1={shiftdata} /> : null
}
</Suspense>
Upvotes: 0
Reputation: 519
I faced this issue as well, and it turns out that the error was being thrown because I had brackets around my import statement, which meant that I was returning nothing
const MyComponent = React.lazy(() => {
import('./scenes/MyComponent')
)};
Once I removed the brackets everything worked perfectly, since I was not actually returning something.
const MyComponent = React.lazy(() =>
import('./scenes/MyComponent')
);
Upvotes: 5
Reputation: 1062
After looking at my own question, I figured it out looking at the dependencies. My react
and react-dom
were on different major versions.
This fixed it:
npm i -D [email protected]
Upvotes: 34