My react-hot-loader does not work properly.
If I do not add ["react-hot-loader/babel"] to .babelrc, the page will not be refreshed but will change. It seems that React-hot-loader replaced the entire reactroot element, and React's state is lost.
If I add ["react-hot-loader/babel"] to .babelrc, I can see xxx.hot-update.js in the head element. But there is no change in the page. React's state is not lost and the change did not take effect.
Add ["react-hot-loader/babel"] to .babelrc and the change take effect.
Add ["react-hot-loader/babel"] to .babelrc and the change did not take effect.
React Hot Loader version: 3.0.0-beta.7.
Run these commands in the project folder and fill in their results:
node -v: 6.11.0npm -v: 3.10.10.Here is the npm script:
"start": "webpack-dev-server --hot --progress --env dev"
And the webpack.config.js.
My english is poor......
@Kannnnng - yet, without RHL HOT Update will destroy application state. With RHL it might(not always) keep it.
But anyway - where is NamedModulesPlugin and do you include react-hot-loader/patch?
@theKashey Thanks for your help~
I have already added NamedModulesPlugin to the plugins array, and here is the code in my webpack.config.js
if (process.env.NODE_ENV === 'production') {
.......
} else {
plugins = [
......
/* 在组件热加载的时候显示更新的组件名而不是原本的组件 ID */
new webpack.NamedModulesPlugin(),
......
]
}
And I have also added react-hot-loader/patch to the entry, here is the code in my webpack.config.js
if (process.env.NODE_ENV === 'production') {
.......
} else {
entry = {
app: [
// 'babel-polyfill',
'react-hot-loader/patch',
path.resolve(APP_PATH, 'index.js'),
],
}
......
}
I have done what you said. But this problem still exists. Do you know what's going on?
@Kannnnng - do you wrap your Application by AppContainer?
@theKashey Yes, I did that. The code is in app/index.js.
const render = (Component) => {
ReactDOM.render(
<Provider store={store}>
<MuiThemeProvider>
<AppContainer>
<Component />
</AppContainer>
</MuiThemeProvider>
</Provider>,
document.getElementById('app') // eslint-disable-line
)
}
render(Routes)
if (module.hot) {
module.hot.accept('./routes', () => {
render(Routes)
})
}
🤷♂️ I cant help without example.
@theKashey Oh sorry, I forgot pushing my repository address. Here is the Project.
There are some Chinese comments in the code. You can ignore them.
@Kannnnng - but there is no RHL-related code inside :(
@theKashey Really? The configuration file is webpack.config.js, and I import the React-hot-loader in app/index.js.
Oh, please note that the branch is develop.v2 rather than master.
@Kannnnng - ok, that was easy :)
The roots of evil are inside "react-loadable". It is designed to load a Component only on mount action. In proper RHL you will not have remount action (and will not lose internal state).
This a common "issue" for near to all "loaders".
How to solve - use https://github.com/theKashey/react-hot-component-loader, it is designed to work with HMR and quite handy.
@theKashey I add the react-hot-component-loader to my code but another problem arises. This error occurred in react-hot-component-loader/src/index.js.
ERROR in ./~/.1.0.1@react-hot-component-loader/src/index.js
Module parse failed: /Users/kang/Documents/Project/React-demo/node_modules/.1.0.1@react-hot-component-loader/src/index.js Unexpected token (61:8)
You may need an appropriate loader to handle this file type.
| if (AsyncComponent) {
| return (
| <AppContainer>
| <AsyncComponent {...this.props} />
| </AppContainer>
@ ./app/routes.js 8:0-49
@ ./app/index.js
@ multi ./~/.2.4.5@webpack-dev-server/client?http://localhost:9000 webpack/hot/dev-server react-hot-loader/patch ./app/index.js
It told me that I need an appropriate loader to handle this file type. But I have used babel-loader for all the JS files. I can not figure out where it was wrong......
By the way, it seems that the root of the problem was not react-loadable. Even if I do not use react-loadable, the problem still exists.
@Kannnnng - eh, webpack3 three shaking is so weird thing - from one side they ask you to ship es6 sources, from other - not working out of the box :)
I'v bumped package version and not it might work.
PS: I'v just remove loader from Routes, and RHL work perfectly. So problem is with Loader, as expected.
@theKashey Are you running my project? Why is the problem still exists when I run my project after I remove react-loadable and react-router......
@Kannnnng - for me problem is __not__ exists without react-loadable.
@theKashey It does not work for me......so sad......
I have removed irrelevant code as much as possible. But this bug fell in love with me. I can not get rid of it......Orz
OH MY GOD! I find the root of this problem!
The reason is that I use the latest React syntax in my React components. In my code, I am writing my components like this:
class Test extends React.Component {
static propTypes = {
......
}
static defaultProps = {
......
}
constructor(props) {
super(props)
this.state = {
......
}
}
handleOnClickliked = () => {
......
}
render() {
......
}
}
Please note this code: static propTypes = {} and static defaultProps = {}. It belongs to ES7, and it needs to use the babel-preset-stage-0 for transcoding. But it can not be transcoded when add the "plugins": ["react-hot-loader/babel"] to the .babelrc. So if I write code like this:
class Test extends React.Component {
constructor(props) {
super(props)
this.state = {
......
}
}
handleOnClickliked = () => {
......
}
render() {
......
}
}
Test.propTypes = {
......
}
Test.defaultProps = {
......
}
This works fine! So I think that the reason of this problem is react-hot-loader/babel can not handle ES7!
@Kannnnng - it should not be a problem, as long I am using static class members and everything is ok.
And, anyway, there is no matter for babel plugin how do you create your classes - it just looks for a variable.
PS: You should not use state-0, use https://babeljs.io/docs/plugins/transform-class-properties/ instead.
@theKashey Oh yes. The wrong code is not here. This morning I reused the static class method and it works fine. And the problem is really about the react-loadable. You are right!
But how to fix that? I use react-hot-component-loader that you suggested but there was a mistake mentioned above......:(
@theKashey Aha, You updated this tool yesterday. I did not even notice that. Want to cry......
But there are two problems about react-hot-component-loader.
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] unexpected require(./app/containers/Home/index.js) from disposed module ./app/routes.js
[HMR] Updated modules:
[HMR] - ./app/components/DiscussionBottomToolBar/index.js
[HMR] - ./app/containers/Home/index.js
[HMR] - ./app/routes.js
[HMR] App is up to date.
The first is easy to fixed.
The second warning arised when the hot update is complete. This seems to be a general problem.
Second is also quite easy to solve. I just need your repo to test everything.
I dont know why, but I didn't face that error.
@Kannnnng - tested on your repo and fixed. Just bump the version.
@theKashey It works fine for me now! Thanks a lot for your help. Your work is so outstanding!
Most helpful comment
@theKashey It works fine for me now! Thanks a lot for your help. Your work is so outstanding!