React-hot-loader: v3: Hot Loading does not work when route component is functional

Created on 4 Aug 2016  Â·  15Comments  Â·  Source: gaearon/react-hot-loader

Reloads are not patching as expected when route component is stateless/functional.

I was able to confirm this by making the top component into a class and hot loading started to work.

Let me know if you want me best way put together an example.

Most helpful comment

@kwelch I have a working Webpack 2 example here.

All 15 comments

I have same problem.

The same.

Same problem.

{
  "presets": [
    "react",
    "es2015",
    "stage-0"
  ],
  "plugins": [
    "transform-runtime",
    "transform-flow-strip-types"
  ]
}
'use strict';

const path = require('path');

const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const HtmlPlugin = require('html-webpack-plugin');

const SRC_PATH = path.join(__dirname, 'src');
const DIST_PATH = path.join(__dirname, 'dist');

module.exports = {
  context: SRC_PATH,

  entry: {
    app: './app',
  },

  output: {
    path: DIST_PATH,
    filename: '[name].js',
    publicPath: 'http://localhost:8080/',
  },

  resolve: {
    extensions: [
      '',
      '.js',
      '.scss',
    ],
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        include: SRC_PATH,
        loaders: [
          'react-hot-loader/webpack',
          'babel',
        ],
      },

      {
        test: /\.scss$/,
        include: SRC_PATH,
        loaders: [
          'style',
          'css?sourceMap!postcss!sass?sourceMap',
        ],
      },
    ],
  },

  postcss: [autoprefixer],

  plugins: [
    new webpack.NoErrorsPlugin(),
    new HtmlPlugin({
      template: path.join(SRC_PATH, 'index.html'),
      inject: false,
      favicon: false,
    }),
  ],

  devtool: 'eval',

  devServer: {
    contentBase: DIST_PATH,
    historyApiFallback: true,
  },
};
{
  "name": "yo",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --hot"
  },
  "devDependencies": {
    "autoprefixer": "^6.4.1",
    "babel-loader": "^6.2.5",
    "babel-plugin-transform-flow-strip-types": "^6.14.0",
    "babel-plugin-transform-runtime": "^6.15.0",
    "babel-polyfill": "^6.13.0",
    "babel-preset-es2015": "^6.14.0",
    "babel-preset-react": "^6.11.1",
    "babel-preset-stage-0": "^6.5.0",
    "css-loader": "^0.24.0",
    "html-webpack-plugin": "^2.22.0",
    "node-sass": "^3.8.0",
    "postcss-loader": "^0.11.1",
    "react-hot-loader": "^3.0.0-beta.3",
    "sass-loader": "^4.0.1",
    "style-loader": "^0.13.1",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.15.1"
  },
  "dependencies": {
    "axios": "^0.14.0",
    "bootstrap": "^4.0.0-alpha.3",
    "classnames": "^2.2.5",
    "history": "^3.2.1",
    "react": "^15.3.1",
    "react-dom": "^15.3.1",
    "react-redux": "^4.4.5",
    "react-router": "^2.7.0",
    "react-router-redux": "^4.0.5",
    "redux": "^3.5.2",
    "redux-logger": "^2.6.1",
    "redux-thunk": "^2.1.0"
  }
}

Hi @kwelch, I'm familiar with RR but don't use it regularly, so I might be missing some context.

By "route component" do you mean the component holding your top-level RR config? I added a quick example here with a route config that returns React elements, but is used like a called function rather than a functional React component. In this case, the routes are defined separately and passed as props to the component rendering <Router/>.

I'm not sure what approach you're trying to take, do you have your own example you can show me?

What I meant was the first example, but where Counter is a functional/stateless component instead of a class.

With the API change in RR v4, I am not having this issue. Sorry for extra comment, cannot edit on mobile.

We'll still want to support RR 2/3 to some degree. But I'm not sure Counter would be possible as a stateless component since it relies on having state and lifecycle methods. You might be saying something else though, mind to clarify?

Right counter could not be stateless in this scenario, in my scenario it
was a layout page that defined the page and rendered, Counter.

On Sat, Oct 1, 2016, 10:07 PM Cale Newman [email protected] wrote:

We'll still want to support RR 2/3 to some degree. But I'm not sure
Counter would be possible as a stateless component since it relies on
having state and lifecycle methods. You might be saying something else
though, mind to clarify?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/gaearon/react-hot-loader/issues/335#issuecomment-250950842,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABPE3Dj3jXllkGwGcgY-R6vFK0FC4NsXks5qvx_jgaJpZM4JcSwV
.

Hmm ok. I just tested with a SFC that rendered a Counter as one of its children, and both components reloaded without unmounting the Counter. Would you mind sharing an example where this doesn't work when you get the time?

Yeah, not a problem. May not be able to get it until tonight, but will post it once I have.

So I was able to reproduce, but I would easily consider it to be an edge case. Commit with my diffs

Cases as I see it:

  • Dynamic Routing
  • Layout as Functional Component
  • Change made to Home.js

I hope this helps.

Thanks for the update. Yes, dynamic/async routes with require.ensure are a problem, which we're tracking in #288. If you're using Webpack 2, @ctrlplusb has had success with System.import.

On your fork, I replaced all the getComponent keys with synchronous components (same for child routes), and hot reloading worked on all routes, so I'd say the issue is isolated to async routes.

@kwelch I have a working Webpack 2 example here.

@calesce Great. Should I close this since it is tracked in #288? I don't think there are any differences between these issues.

Yep, I'll go ahead

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zlk89 picture zlk89  Â·  3Comments

sandysaders picture sandysaders  Â·  4Comments

Opty1712 picture Opty1712  Â·  4Comments

mqklin picture mqklin  Â·  3Comments

mattkrick picture mattkrick  Â·  3Comments