React-hot-loader: Confused by docs: do I need module.hot.accept(... after export default hot(module)(App)?

Created on 15 Jan 2019  路  20Comments  路  Source: gaearon/react-hot-loader

// package.json
    "react-dom": "npm:@hot-loader/react-dom", // do I need this?
// webpack.config.js
module.exports = {
  entry: [
    'react-hot-loader/patch',  // do I need this?
    './src/entrypoint.js'
  ],
  // ...
// babel.config.js
module.exports = {
  plugins: ['react-hot-loader/babel'], // do I need this?
  // ...
// App.js
import { hot } from 'react-hot-loader/root';
import * as React from 'react';

const App = () => <div>Hello World!</div>;

export default hot(App); // do I need this?
// entrypoint.js
import React from 'react';
import ReactDOM from 'react-dom';

import { AppContainer } from 'react-hot-loader'; // do I need this?
import App from './App';

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

render(<App />);

// do I need this?
module.hot.accept('./App.js', () => {
  const NextApp = require('./App.js').default;
  render(<NextApp />);
});

Is there an up-to-date full example of rendering a hot-exported component?

Most helpful comment

// package.json
    "react-dom": "npm:@hot-loader/react-dom", // do I need this?
  • This is optional, but highly encouraged.
// webpack.config.js
module.exports = {
  entry: [
    'react-hot-loader/patch',  // do I need this?
    './src/entrypoint.js'
  ],
  // ...

Only if you are not using hot-loader/react-dom and also yet optional

// babel.config.js
module.exports = {
  plugins: ['react-hot-loader/babel'], // do I need this?
  // ...

__yes__, we need this.

// App.js
import { hot } from 'react-hot-loader/root';
import * as React from 'react';

const App = () => <div>Hello World!</div>;

export default hot(App); // do I need this?

__yes__, this is the most important moment

// entrypoint.js
import React from 'react';
import ReactDOM from 'react-dom';

import { AppContainer } from 'react-hot-loader'; // do I need this?
import App from './App';

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

render(<App />);

// do I need this?
module.hot.accept('./App.js', () => {
  const NextApp = require('./App.js').default;
  render(<NextApp />);
});

__no__, please never do it without understanding how HMR works.


Is there an up-to-date full example of rendering a hot-exported component?

See examples folder, sorted by last change date.

All 20 comments

@lxe

The below examples should get you up and running with v4.6.3. I removed the typescript integrations since I use that as well. This should work though.

// babel.config.js
module.exports = {
  // ... other presets and plugins
  plugins: ["react-hot-loader/babel"]
}
// webpack.config.js
const { resolve } = require('path')
const webpack = require('webpack')

module.exports = {
  mode: 'development',
  // Entry point for build.
  entry: ['./index.js'],
  // Output to './public'.
  output: {
    filename: 'bundle.js',
    path: resolve(__dirname, 'public'),
    publicPath: '/',
  },
  // Development server.
  devServer: {
    contentBase: './public',
    hot: true,
    port: 8080,
  },
  module: {
    rules: [
      {
        exclude: /node_modules/,
        test: /\.(js|jsx)$/,
        use: ['babel-loader'],
      }
    ],
  },
  resolve: {
    extensions: ['*', '.js', '.jsx', '.json'],
  },
  plugins: [
    // Hot reloading.
    new webpack.HotModuleReplacementPlugin(),
  ],
}

// Entry point of application
import React from 'react'
import { hot } from 'react-hot-loader/root'

const App = () => <h1>Hello World</h1>

export default hot(App)
// package.json
    "react-dom": "npm:@hot-loader/react-dom", // do I need this?
  • This is optional, but highly encouraged.
// webpack.config.js
module.exports = {
  entry: [
    'react-hot-loader/patch',  // do I need this?
    './src/entrypoint.js'
  ],
  // ...

Only if you are not using hot-loader/react-dom and also yet optional

// babel.config.js
module.exports = {
  plugins: ['react-hot-loader/babel'], // do I need this?
  // ...

__yes__, we need this.

// App.js
import { hot } from 'react-hot-loader/root';
import * as React from 'react';

const App = () => <div>Hello World!</div>;

export default hot(App); // do I need this?

__yes__, this is the most important moment

// entrypoint.js
import React from 'react';
import ReactDOM from 'react-dom';

import { AppContainer } from 'react-hot-loader'; // do I need this?
import App from './App';

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

render(<App />);

// do I need this?
module.hot.accept('./App.js', () => {
  const NextApp = require('./App.js').default;
  render(<NextApp />);
});

__no__, please never do it without understanding how HMR works.


Is there an up-to-date full example of rendering a hot-exported component?

See examples folder, sorted by last change date.

rockchalkwushock any chance you could also include a copy with your typescript integrations as
well?

@Mknight492 - I personally use following configuration:

  • ts-loader
  • babel-loader (for react-hot-loader, jsLingui and so on)
{
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: [
          'babel-loader',
          'ts-loader'
        ],
      },

The current configuration, described in a readme(use babel 7 ts preset), is probably wrong - _babel script_ is not real TypeScript, and may not work for everybody.

@Mknight492 here is a post from my blog on how to setup a React project with TS and hot reloading based on the latest version of react-hot-loader. There is a link in the article to a repository as well. Hope this helps you out!

Mine 2 cents about @rockchalkwushock article:

  • (very common mistake) you __dont need to addHotModuleReplacementPlugin. It will actually lead to __TWO__ plugins exists simultaneously. Just specifyhot` option for webpack. THAT'S ALL!
  • (馃槩) typescript with isolatedModules is not _typescript_. It's _babelscript_. It might not work if you not re-exporting types, which is a common thing in "enterprise"(or properly decomposed) code.

You may found many different configurations among our examples folder. And all works.

@theKashey thanks for the input I appreciate it. I wasn't aware of point one and I'm still relatively new to TS land so I'm learning new things there everyday.

@theKashey - why do you say not to add HotModuleReplacementPlugin?
The readme here points to https://webpack.js.org/guides/hot-module-replacement/#enabling-hmr where it clearly says to add it. Maybe a clarification should be added in the readme?

If I remove the HotModuleReplacementPlugin I get an error "[HMR] Hot Module Replacement is disabled." and the app does not load at all.
If I do add it the app loads but but then does a full page reload on code changes.
I pass hot: true as option to the server since I use the dev server API.

(This last note probably deserves its own issue but the question remains)

hot=true should be enough for webpack-dev-server. You have to use HotModuleReplacementPlugin only if you are using a custom dev server.

Hello @theKashey

Is this

// webpack.config.js
module.exports = {
  entry: [
    'react-hot-loader/patch',  // do I need this?
    './src/entrypoint.js'
  ],
  // ...

the "webpack plugin" as it's called everywhere in the readme?

No, "that" is not a webpack plugin (it's a loader) - it's just an entry point settings, and you don't need "this".

I think that the confusion is coming from the Getting Started page of the documentation website, which contradicts the README.md. Are there plans to update that documentation?

Oh, it sooo obsolete. We haven't updated the site since v3 (two years)

Are there plans to update it? (Aka should there be a PR that changes it or a PR that redirects to the readme here on GitHub?)

We all are living beings. If you are able to create the PR you are talking about - feel free to do it. And that would be a fastest way to solve the problem.

Sorry, I didn't mean to come across as brusque or disrespectful - my question was more about whether the documentation site was abandoned and so should redirect to the current readme or if the idea is to have the site and it just hasn't been prioritized. Knowing that, I'd be able to start working on a PR that aligns with the goals of the project rather than a potentially tangential one.

You may threat the site as a abandoned. gh-pages was normally updated around 3 years ago.

Thanks @theKashey, I've been chasing configurations for too much time now and your comment made things clear.

This solved my problem!

npm i react-hot-loader

import {hot } from 'react-hot-loader/root'
import React from 'react'
import ReactDOM from 'react-dom'
import { Day1 } from './day1

hot(this)

ReactDOM.render(<Day1 />, document.getElementById("root"));

hot(this)? That's absolutely not correct, and all it does (right) - setups HMR for the current file, ie makes module.hot.accept

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mattkrick picture mattkrick  路  3Comments

tiberiumaxim picture tiberiumaxim  路  4Comments

lemonmade picture lemonmade  路  3Comments

esturcke picture esturcke  路  3Comments

reintroducing picture reintroducing  路  4Comments