Description
I'd like to confirm the 'correct' way to have CRA + HMR + React now we are on version 1 and using webpack 2, and that all these thoughts are correct. They may be useful to others adding HMR.
Examples have been updated incorporating feedback
Why Hot Module Reload
Adding in HMR changes your application from full page refresh to refreshing just the app.
In most cases this will make the page reload faster.
If you are using external state management such as Redux, you can have your redux state remain when component changes are made.
Note: This is not same a component based hot-module-reloading where state within your react application remains unchanged when making changes to your source code. HMR will remove any component-based state. That is currently unsupported by CRA, more information see react-hot-loader and status post by gaereon.
Hot Module Reload without Redux
index.js
// regular imports
ReactDOM.render(<App /> , document.getElementById('root'))
if (module.hot) {
module.hot.accept('./App', () => {
ReactDOM.render(<App />, document.getElementById('root'))
})
}
As seen here and in issue #897
Hot Module Reload with Redux (or similar state management)
index.js
// Normal imports
import { Provider } from 'react-redux'
import configureStore from './redux/configureStore'
const store = configureStore()
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('root'))
if (module.hot) {
module.hot.accept('./App', () => {
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root'),
)
})
}
configureStore.js (or similar)
import { createStore } from 'redux'
import rootReducer from './reducers'
const configureStore = () => {
const store = createStore(rootReducer)
if (process.env.NODE_ENV !== "production") {
if (module.hot) {
module.hot.accept('./reducers', () => {
store.replaceReducer(rootReducer)
})
}
}
return store
}
export default configureStore
Activity
gaearon commentedon May 22, 2017
With Webpack 2 (which CRA now uses) this should be enough:
It's because
App
is live-bound to ES6 import in Webpack 2.Same with the other example:
bfncs commentedon Jun 11, 2017
Really helpful, thanks a lot! Note, that the component you are hot reloading (
<App />
in your example) needs to be class component, it will not work with a pure functional component.dreyks commentedon Jul 25, 2017
for some weird reason my state gets wiped clean on hot reloading. I'm using plain react, no redux
rmoorman commentedon Jul 27, 2017
Same here (but using a simple redux setup). When I change my App component, the state seems to be gone.@ro-savage, @bfncs or @gaearon is there some working example on github that can be cloned and run (CRA + minimal redux)?
Edit: suddenly it started working ... and I have no idea why ...
nealoke commentedon Jul 27, 2017
@rmoorman would you be able to share a small repo where all the code is present? I've been trying to get this to work for a couple of hours now and can't succeed...
I can see that the HMR picks up the change in the
rootReducer
and it recompiles fine. But when I check to see if the changedreducer
actually changed, I can see that it does not change anything.Any help would be awesome...
nealoke commentedon Jul 27, 2017
@bfncs @gaearon Am I missing something here?
index.js
Store.js
rmoorman commentedon Jul 27, 2017
@nealoke here you go. Pretty basic. Whenever you change the app component (or the rootReducer), state is kept.
zanjs commentedon Aug 5, 2017
Thinks 😜
sdhhqb commentedon Aug 8, 2017
thanks! these help a lot!
nealoke commentedon Aug 8, 2017
@rmoorman thanks, but I can't find a difference in setup between yours and my snippet though 😞
@sdhhqb did you get it to work with reducers as well?
sdhhqb commentedon Aug 8, 2017
@nealoke yes, it's working, the store can update when I change reducers. I use gaearon's approach.
rmoorman commentedon Aug 8, 2017
@nealoke but does cloning the example repo and running the code work for you (the example is basically what @Gearon suggested)? I would suggest to take one of the working approaches and incrementally go from there towards your piece of code in order to find the culprit.
gnapse commentedon Sep 27, 2017
@bfncs I just got it to work with a pure functional component. Perhaps something has changed since you made that comment?
9 remaining items