Dynamic Lazy Loading using React.Lazy (16.6.0)

Viewed 6095

I get an array like

{Path:xxx, 
Component:"./xxx/ComPXX"}

from my API and based on that create my application's routes. At the moment I'm using React-Loadable (5.5.0) and React-Router (4.4.0-betax to avoid warnings in strict mode). See working example here.

Since React 16.6 has introduced React.lazy, I'm trying to migrate my solution, however I'm facing errors and difficulties however I try to do this. You can see migrated (failing) code here.

Any Idea why this isn't working? Can it be because React.Lazy doesn't accept variables?

1 Answers

You got 2 3 main issues:

  1. In this line:

    var c = <dynamicLoader component={prop.component} />;
    

    User-Defined Components Must Be Capitalized. so change it to this:

    var c = <DynamicLoader component={prop.component} />;
    

    Obviously you'll need to change the declaration as well:

    function DynamicLoader(props) {
      return (
        <Suspense fallback={<div>Loading...</div>}>
          React.lazy(() => import(`${props.component}`))
        </Suspense>
      );
    }
    
  2. In this line

    return <Route exact path={prop.path} component={c} key={key} />;  
    

    As the name of the prop component suggests, you need to pass a component and not an element you can read more about the difference in the DOCS.

    So you'll need to change it to this:

    return <Route exact path={prop.path} component={() => c} key={key} />;
    
  3. You are right. I missed the children part, you are rendering a string. You can create a variable and just render it as the child:

    function DynamicLoader(props) {
      const LazyComponent = React.lazy(() => import(`${props.component}`));
      return (
        <Suspense fallback={<div>Loading...</div>}>
          <LazyComponent/>
        </Suspense>
      );
    }
    
Related