sthenault
sthenault

Reputation: 15125

componentDidMount unexpectedly called after move from react-loadable to react.lazy

In my project I used to rely on react-loadable to do some code spliting, lazy loading together with react-router. Something like:

<Route component={component} />

with

Component = Loadable({
    loader: () => import(/* webpackChunkName: "Analyze" */ "./components/Analyze"),
})

The Analyze component implements componentDidMount and use router's history.push on state change. When a new url is pushed with some parameter changed, but still leading to this same "Analyze" component, only componentDidUpdate is called. I updated this code to use React.lazy:

<Route component={(_props: any) =>
          <LazyComponentWrapper>
              <Component {..._props} />
          </LazyComponentWrapper>
        } />

with

Component = React.lazy(() => import(/* webpackChunkName: "Analyze" */ "./components/Analyze")),

and

function LazyComponentWrapper({ children }) {
  return (
    <Suspense fallback={<div>{LOADING}</div>}>
        {children}
    </Suspense>
  );

but now componentDidMound is unexpectedly called every time. It's not clear to me wether this have to do with React.lazy or with react-router. Any clue ?

Upvotes: 0

Views: 138

Answers (1)

StackedQ
StackedQ

Reputation: 4139

According to docs maybe its better to move Suspense out of Route component, try this:

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const Component = React.lazy(() => import(/* webpackChunkName: "Analyze" */ "./components/Analyze"))

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/analyze" component={Component}/>
      </Switch>
    </Suspense>
  </Router>
);

Upvotes: 1

Related Questions