2

I'm trying to implement a "lazy-route" to achieve code splitting in my React single page app.

  • It's all client side rendered
  • I'm using react-router
  • Also using Webpack

I have this component that renders all my routes.

AllRoutes.js

function AllRoutes() {
  return(
    <Switch>
      <Route exact path={"/ROUTE_A"} component={Component_A}/>
      <Route exact path={"/ROUTE_B"} component={Component_B}/>
      // AND SO ON
    </Switch>
  );
}

I'm trying to do something like this:

import LazyRoute from './LazyRoute';

function AllRoutes() {
  return(
    <Switch>
      <Route exact path={"/ROUTE_A"} component={Component_A}/>
      <Route exact path={"/ROUTE_B"} component={Component_B}/>
      <Route exact path={"/ROUTE_C"} component={LazyRoute}/>  // THIS SHOULD LAZY LOAD
    </Switch>
  );
}

And this is what I've tried:

LazyRoute.js

function LazyRoute() {
  return import("@pages/Component_C").then(({default: Component_C}) => {
    return Component_C;
  });
}

export default LazyRoute;

Webpack seems to be doing its part in splitting this LazyRoute bundle:

enter image description here

But I'm getting this error:

enter image description here

I know I'm retuning a Promise by doing return import(). But isn't this the whole point?

7
  • You can use react lazy here...why not using it ? Commented Jul 2, 2020 at 6:38
  • @yAzou I know.. I will probably use React.lazy or Loadable, but I like to do a raw implementation so I can understand it better. Commented Jul 2, 2020 at 6:41
  • I was able to make this work at some point, but I completely forgot how I did it. Tried to look up in old files but couldn't find it. Commented Jul 2, 2020 at 6:42
  • I can post an example of your implementation using react lazy if you wish Commented Jul 2, 2020 at 6:42
  • Thanks, I haven't tried with React.lazy yet. I'll upvote it, but I'm still looking for the "raw" solution, using only dynamic imports. Commented Jul 2, 2020 at 6:46

2 Answers 2

3

Hi you can use React Lazy here. Here is an example that should work using your implementation.

import React, { lazy } from "react";
import { Route, Switch } from "react-router-dom";
import LazyRoute from './LazyRoute';

const Component_C = lazy(() => import("./Component_C"));

function AllRoutes() {
  return (
<Switch>
  <Route exact path={"/ROUTE_A"} component={Component_A}/>
  <Route exact path={"/ROUTE_B"} component={Component_B}/>
  <Route exact path={"/ROUTE_C"} component={LazyRoute(Component_C)}/>  // THIS SHOULD LAZY LOAD
</Switch>
  );
}

LazyRoute.js

import React, { Suspense } from "react";

function LazyRoute(Component) {
  return props => (
    <Suspense fallback={<div>Loading...</div>}>
      <Component {...props} />
    </Suspense>
  );
}
export default LazyRoute;
Sign up to request clarification or add additional context in comments.

Comments

1

Just found an old solution that I wrote for this.

import React, { useEffect, useState } from 'react';
import styled from 'styled-components';

const LS = {};

LS.Container_DIV = styled.div`
`;

async function lazyRender() {
  const TestContainer = (await import("@pages/Test/TestContainer"));
  return new Promise((resolve) => {
    resolve(TestContainer);
  });
}

function LazyRoute(props) {
  console.log('Rendering LazyRoute...');

  const [lazyLoading,setLazyLoading] = useState(true);
  const [LazyComponent,setLazyComponent] = useState(null);

  useEffect(() => {
    async function getLazyComponent() {
      const component = await lazyRender();
      setLazyComponent(component);
      setLazyLoading(false);
    }
    getLazyComponent();
  },[]);

  return(
    lazyLoading ?
      <div>I am Lazy Loading....</div>
    : <LazyComponent.default {...props}/>
  );
}

export default React.memo(LazyRoute);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.