Abhijeet Singh
Abhijeet Singh

Reputation: 1062

Uncaught undefined error when using React.lazy

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

Answers (3)

harith
harith

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

Michael M.
Michael M.

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

Abhijeet Singh
Abhijeet Singh

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

Related Questions