react-hot-loader: Asynchronous React Router v3 routes fail to hot-reload
Hey there! I’m having some difficulty getting react-hot-loader@3.0.0-beta.1 to hot-reload changes to views that are passed to React Router as lazy-loaded POJOs. Updating a view class triggers the usual console messages and throws the warning about changing <Router history>, but the rendered output doesn’t refresh. Curiously, though, changing the components that the views require immediately hot-reloads them, even within the selfsame non-reloading async views.
Here’s a quick screencast demonstrating the issue:

…and here’s the code base that screencast’s taken from: https://github.com/phyllisstein/hildy/tree/react-hot-3. (The master branch of which repo is still using react-transform-hmr without any evident issues.)
I’d be grateful for any suggestions you can provide, and happy to offer more troubleshooting info if I can! Thanks for looking into this.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 12
- Comments: 32 (4 by maintainers)
Commits related to this issue
- This is no longer needed with the upgrade to react router 4 see https://github.com/gaearon/react-hot-loader/issues/288 for details — committed to erchaves/kyt by erchaves 6 years ago
I ran into the problem with hot reloading async routes and updated by additionally registering a
module.hot.acceptin therequire.ensure()callbacks. E.g. like thisIs there any update regarding this issue?
So far there has been only a few suggestions, each having its own drawbacks and all being but workarounds:
Provide “key” prop to
<Route />Fixed the problem, but as mentioned causes deep re-render, therefore loosing components’ state. However, you can find this workaround in officially listed examples of
react-hot-loader(i.e. here).Using
asyncComponentfromreact-async-componentAs suggested here, it is possible to wrap the modules you wish to load async with
asyncComponentand pass them ascomponentprop toRoutedirectly. This will eliminate hot-reloading issue, however forces you to create additional files doing nothing but resolving modules async.Various other workarounds
Which are not meant for good code maintenance.
So, it this somehow being solved, or already has been solved with the new release of
react-hot-loader?@flut1 yeah that will allow updates to happen, but component state is lost because it’s deeply re-rendering all of the components, so it’s not the ideal workaround.
Just wanted to add that I was playing around with
require.ensureand RR, using @sthzg’s solution, and it seems to work fine withgetChildRoutes, but notgetComponent.It looks like the
getComponentcallback can’t be called multiple times (tested out withsetTimeoutloading a different component). Another reason to move on to RR4? 😛@kettanaito You’re right, but read this:
And maybe it’s worth a reading: https://github.com/ReactTraining/react-router/tree/v4.0.0-beta.8#why-did-you-get-rid-of-feature-x
I ran into the same issue where HMR was not working with react-router, and I managed to work around the issue, so I thought I’d share my solution:
Used with the Router like this:
I worked around the getComponent() issue by adding a key prop to Router that changes on each hot update. This will force a different Router instance to be created, and re-executing getComponent() calls. This also fixed the
You cannot change <Router router>warnings. Not sure if creating new Router instances causes other (performance) issues but it seems to work for me.With webpack 2 in System.import HMR too doesn’t work.
I close it. React Router v4 is supported and stable.
@morajabi sorry, there is nothing about SSR in the migration guide. Regardless, the issue with v3 still remains, and there should be some statement how to cope with it.
@morajabi I haven’t got enough time to read about it. So far, I don’t see how to migrate my code to use
react-router4, especially since my SSR relies onmatch, which was removed from the fourth version.Using anything that is not an ES6
importis probably the biggest complicating factor for hot reloading.Also note that, if you save the
require('./About').defaultin thecomponentproperty, it will never ever get updated if you don’t write code to do it. This would also be the case with ES6importthough (imports are live, but if you save a copy of the current value elsewhere the copy isn’t).Grain of salt and all, but it seems this issue has mysteriously resolved itself with Webpack 2.2.0. Previously, in order to make hot reloading work, I was manually adding chunks of code like this to any parent view that asynchronously loaded children:
I removed all such lines on a whim to see what it’d break, and much to my surprise and delight, HMR continued to function beautifully.
I don’t think anything relevant has changed in my setup other than the Webpack version, but this wasn’t carefully tested. Would be glad to see if others could corroborate my story.
@dferber90 the main point of having a chunking in development is the profiling, f.e. with help of such tools like webpack-dashboard. That allows for instance immediately see an impact of the changes to files size without necessity to build and switch to prod. So the drawback is pretty much serious.
Anyway what’s a main bottleneck in this issue making only pure stateless components reloaded in chunks? Router, react-hot-reloader or bundler?
Regarding ‘…’ character in my snippet - that’s just skipped pathes to component files, nothing else