4

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 Answer 1

9

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>
      );
    }
    
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for Answer. I made the changes as you suggested, no more errors. However now when I click on a route instead of seeing the component I see something like "React.lazy(() => import($./HomeB))" instead of the component.
Sorry! Looks like I forgot to have {} around the React.lazy.. and it was being treated like a string. adding {}, I'm getting errors now. Can you have a look please? Thx codesandbox.io/s/3rv3yn0p5p
Check the update to the answer, by the way, wrapping it with {} won't make it a react element, you'll need to use JSX which is just a syntactic sugar for React.createElement
I would recommend using the render prop of Route and not component since component calls React.createElement and if you put an inline function there, it will cause a re-render. You can see some more information here: reacttraining.com/react-router/web/api/Route/component

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.