Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Lazy Loading using React.Lazy (16.6.0)

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?

like image 652
Asha Avatar asked Jan 27 '23 06:01

Asha


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>
      );
    }
    
like image 130
Sagiv b.g Avatar answered Jan 31 '23 23:01

Sagiv b.g