React-hot-loader: add the "plugins": ["react-hot-loader/babel"] and the page has not changed

Created on 2 Sep 2017  ·  21Comments  ·  Source: gaearon/react-hot-loader

Description

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.

Expected behavior

Add ["react-hot-loader/babel"] to .babelrc and the change take effect.

Actual behavior

Add ["react-hot-loader/babel"] to .babelrc and the change did not take effect.

Environment

React Hot Loader version: 3.0.0-beta.7.

Run these commands in the project folder and fill in their results:

  1. node -v: 6.11.0
  2. npm -v: 3.10.10.
  3. Operating system: Windows 10.0.14393.
  4. Browser and version: Google Chrome 60.

Here is the npm script:
"start": "webpack-dev-server --hot --progress --env dev"

And the webpack.config.js.

My english is poor......

Most helpful comment

@theKashey It works fine for me now! Thanks a lot for your help. Your work is so outstanding!

All 21 comments

@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!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tiberiumaxim picture tiberiumaxim  ·  4Comments

mqklin picture mqklin  ·  3Comments

reintroducing picture reintroducing  ·  4Comments

theKashey picture theKashey  ·  4Comments

adesmet picture adesmet  ·  4Comments