Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React lazy components not loaded on dynamic routes

I used react lazy and suspense on dynamic routes but somehow I cannot render the lazy loaded components.

I've already searched about the use of lazy on routes but I haven't seen anyone use it on dynamic(localhost:8080/dynamic/dynamic) routes.

loading components on dynamic routes works for me, lazy loading also works if I have a static route, but when I tried combining the two, the component doesn't load.

here is an example of what I did,

import Loader from './path/toFile';
import Home from './path/toFile';
const LazyLoadedComponent = lazy(() => import('./path/toFile'));

const App = () => {
 return(
  <Router>
     <Switch>

        // Home has multiple views controlled by buttons
        // A view contains selections with corresponding id
       <Route exact path="/:viewType?" component={Home} /> 

       // this component doesn't load when I select something which links me to this dynamic route.
       <Suspense fallback={Loader}>
         <Route path="/viewType/:selectionId" component={LazyLoadedComponent} />
       </Suspense>

     </Switch>
   </Router>
 )
}

I just want my component to be loaded once I go to that route. But the Result is that it loads Home but when I select one from the selection it just shows the index.html with blank I haven't seen any error produced.

like image 515
jhimanjhi Avatar asked Jun 13 '19 08:06

jhimanjhi


2 Answers

I think, no problem in use of react Suspense or lazy. just use Switch in a wrong way.

As react router doc say:

All children of a <Switch> should be <Route> or <Redirect> elements. Only the first child to match the current location will be rendered.

So, Switch component may not recognize the Route which wrapped by the Suspense component.

eg:

import Loader from './path/toFile';
import Home from './path/toFile';
const LazyLoadedComponent = lazy(() => import('./path/toFile'));

const App = () => {
 return(
   <Router>
     <Suspense fallback={Loader}>
       <Switch>
         <Route exact path="/:viewType?" component={Home} /> 
         <Route path="/viewType/:selectionId" component={LazyLoadedComponent} />
       </Switch>
     </Suspense>
   </Router>
 )
}

Here is a example in code sandbox: https://codesandbox.io/s/async-react-router-v4-w-suspense-8p1t6

like image 82
lry Avatar answered Sep 29 '22 09:09

lry


I have found the solution.. or sort of in my case.

I included the publicPath of for my bundles.

I added this on my webpack.config.js

output: {
        publicPath: '/',
      },

and the problem why it didn't work last time is that I'm just refreshing the page knowing have hotmodule installed but it doesn't update my configurations.

So after restarting the server I saw the line

webpack output is served from (the publicPath I declared)

Though I've spent more time than I should have in this problem. It's working now thanks for all of the comments.

like image 22
jhimanjhi Avatar answered Sep 29 '22 10:09

jhimanjhi