7

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.

jhimanjhi
  • 97
  • 1
  • 6

4 Answers4

8

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

lry
  • 728
  • 3
  • 7
  • update the `blockquote` from your answer. You missed some tags. – ravibagul91 Jun 13 '19 at 09:54
  • Thanks for the suggestion, this is actually the current structure of my code, and after this it produces an error 404 which cannot load the chuck(_0.js_) because it is being called in the wrong location (_localhost:8080/viewType/0.js_) which should only be (_localhost:8080/0.js_) or maybe I need to configure my webpack to generate the chunk file on a custom location. I'm trying to find a solution for this, I know that my file exist though because I can access _0.js_ using the latter link. If you have a solution in mind I'll gladly appreciate it. Thanks again. – jhimanjhi Jun 14 '19 at 01:19
2

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.

jhimanjhi
  • 97
  • 1
  • 6
  • this solved for me too. very interesting. i will investigate further to make sure this don't have downsides, but seems far less complicated than other options. – kroe Apr 08 '20 at 23:34
1

Try this,

 <Suspense fallback={Loader}>
   <Switch>
     <Route path="/viewType/:selectionId" />
         <LazyLoadedComponent />
     </Route>
   </Switch>
 </Suspense>
ravibagul91
  • 20,072
  • 5
  • 36
  • 59
  • Hi thanks for the suggestion, I've already tried this one and it produced the same result, the problem I think is the chunk file because it is being loaded in the wrong location. The article you linked was helpful as well especially the dynamic import but it all produced the same result as my previous code. – jhimanjhi Jun 14 '19 at 01:39
0

I have resolved it by doing some extra changes in webpack.config. first eject config using

npm run eject.

webpack.config.js

path: isEnvProduction
            ? path.resolve(__dirname, "..", "build")
            : undefined,
    
filename: isEnvProduction
            ? "[name].js"
            : isEnvDevelopment && "static/js/bundle.js",
    
chunkFilename: isEnvProduction
            ? "[name].chunk.js"
    
publicPath: "/",