Hot loader with react-loadable

Update on 2, September. See last post

Update on 1, June. See last post

So I’m trying the new fancy react-loadable library. The result is very good, webpack can do code splitting perfectly with it. You can read the explanation and tutorial by the author himself here.

But the problem is I use react-hot-loader to make development easier. But when I added loadable component the hot loader seems broken.

// File Routers.jsx
const LoadableHome = Loadable({
loader: () => import('./pages/Home'),
LoadingComponent: MyLoadingComponent,
delay: 200,
});

const LoadableAbout = Loadable({
loader: () => import('./pages/About'),
LoadingComponent: MyLoadingComponent,
delay: 200,
});

const Routers = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>

<hr />

<Route exact path="/" component={LoadableHome} />
<Route path="/about" component={LoadableAbout} />
</div>
</Router>
);

The example code is using react-router v4.

It took me awhile to figure out. I added the old friend to the <Route> component.

Math.random()

So the code will look like this.

<Route exact path="/" component={LoadableHome} key={Math.random()} />
<Route path="/about" component={LoadableAbout} key={Math.random()} />

And react hot loader work again. Yay! Now it’s your turn to try this.

Update 1, June

Although the solution above is working, the entire route reloads each change. Make some components in a route reload and it shouldn’t be.

I found another way and it work better.

First we remove Math.random() from <Route />

Then move Math.random() to the component <Routers/> (in my case is my App entry point) that hold <Route /> components

// File App.jsx
import Routers from './Routers';

const
App = () => (
<Routers key={Math.random()} />
);
export default App;

Then import in to the index entry point that load with react-hot-loader.

// index.js
import { AppContainer } from 'react-hot-loader';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const rootEl = document.getElementById('root');
const render = Component =>
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
rootEl,
);

render(App);
if (module.hot) module.hot.accept('./App', () => render(App));

Cheers!

Update on 2, September

You can see my example setup here. Worked with webpack 3. We still have to use Math.random :(. Be sure to remove Math.random for production build.