What you are reporting:
Every time something is changed inside a react component, the entire application is reloaded (full page reload).
What you think should happen:
Only the changed module should update
React Hot Loader version: 3.0 beta 6
Run these commands in the project folder and fill in their results:
node -v: 6.9.1npm -v: 3.10.9Then, specify:
None at the moment.
With one project, it seems it reloads every time. And I can see this error before the refresh:

With another project, depending on what changes, I can also have a full reload. Usually, I'm never expecting a full reload, especially if only a string changes. So I wonder what could cause this error
Cannot apply update. Need to do a full reload.
Error: aborted because ./src/X.js is not accepted
Update propagation: ./src/X.js -> ./src/Y.js -> 2
I'm seeing the same thing as well.
Node: 6.9.1
NPM: 3.10.8
react-hot-loader: 3.0.0-beta.6

Problem did not occur after downgrading to 1.3.0
Hi, I can't take a look at either of you issues without at least some code to look at.
I have the same problem like mkalish since upgrading from 1.3.0 to 3.0.0-beta6. Always full reload with the same error message. With 1.3.0 hot module update was still working.
I'm using react-hot-loader/patch as Webpack entry point. Problem occurs no matter if i use react-hot-loader/babel plugin or react-hot-loader/webpack loader.
Am I getting it right, that I don't have to call module.hot.accept by hand if I use the react-hot-loader/patch Webpack entry point?
This is my startup code:
import "babel-polyfill";
import "isomorphic-fetch";
import * as React from "react";
import * as injectTapEventPlugin from "react-tap-event-plugin";
import * as ReactDOM from "react-dom";
import {MainContainer} from "./parts/main";
import {createStore, applyMiddleware} from "redux";
import {Provider} from "react-redux";
import * as createLogger from "redux-logger";
import thunkMiddleware from "redux-thunk";
import {MainReducer} from "./common-reducers/main-reducer";
import {StyleRoot} from "radium";
import {AppContainer} from "react-hot-loader";
injectTapEventPlugin();
let store:any = createStore(MainReducer.mainState, applyMiddleware(thunkMiddleware, createLogger()));
ReactDOM.render(
<AppContainer>
<Provider store={store}>
<StyleRoot>
<MainContainer/>
</StyleRoot>
</Provider>
</AppContainer>,
document.getElementById('app')
);
@calesce I was struggling with this problem for a couple days and came across this article that helped me solve my problem
https://medium.com/@rajaraodv/webpacks-hmr-react-hot-loader-the-missing-manual-232336dc0d96#.7kq8oibt5
Important: Use either CLI or Config file but never mix and match the above two ways.
I had followed the migration steps from 1.x to 3,
but the eureka moment was after I moved my CLI params (--inline and --hot) into my webpack.config file, and then everything fell into place
What do you mean with "I had followed the migration steps from 1.x to 3"? The link you posted doesn't contain that.
I still don't have success. Always full reload with the same error message. :(
This is my webpack config (react-hot-loader/babel is added as plugin in .babelc):
const webpack = require('webpack');
const WebpackConfig = require('webpack-config');
const path = require('path');
const buildPath = path.resolve(__dirname, '../www');
const srcPath = path.resolve(__dirname, '../src');
const testPath = path.resolve(__dirname, '../test');
const config = new WebpackConfig().merge({
//Entry points to the project
entry: {
app: [
"react-hot-loader/patch",
"babel-polyfill",
"./src/app/app.tsx"
],
devServer: [
'webpack/hot/only-dev-server'
]
},
//Server Configuration options
devServer: {
contentBase: 'src/www', //Relative directory for base of server
hot: true, //Live-reload
port: 3000, //Port Number
host: 'localhost', //Change to '0.0.0.0' for external facing server
inline: true,
//Map API calls to local backend server
proxy: {
'/api/*': {
target: 'http://localhost:8080'
}
}
},
plugins: [
//Enables Hot Modules Replacement
new webpack.HotModuleReplacementPlugin(),
],
//Config options on how to interpret requires imports
resolve: {
extensions: ["", ".js", ".jsx", ".ts", ".tsx"],
//node_modules: ["web_modules", "node_modules"] (Default Settings)
},
output: {
path: buildPath, //Path of output file
filename: '[name].js',
},
module: {
loaders: [
{
test: /\.ts$|\.tsx$/,
loaders: ['babel-loader', 'ts-loader'],
include: [srcPath, testPath],
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
],
},
});
module.exports = config;
@Q-Man I updated my comment with a link to the migration example
.babelrc
{
"presets":[
"es2015",
"react"
],
"plugins": [
"react-hot-loader/babel",
"transform-object-rest-spread"
]
}
webpack.config.js
module.exports = {
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:9000',
'webpack/hot/only-dev-server',
'./client/index.jsx'
],
output: {
path: '/client',
filename: 'bundle.js',
},
devtool: 'source-map',
devServer: {
hot: true,
contentBase: './client',
inline: true,
port: 9000,
proxy: {
'/**': {
target: 'http://localhost:9001',
bypass: function ( req, res, proxyOptions ) {
if ( req.path === '/' ) return '/index.html'
else return false
},
}
}
},
resolve: {
root: path.resolve('.'),
extensions: ['', '.js', '.jsx'],
},
module: {
loaders: [
{
test: /\.scss$/,
loaders: ["style","css","sass"],
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url',
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel',
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
]
}
index.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import Root from './containers/Root'
import { AppContainer } from 'react-hot-loader'
render( Root )
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./containers/Root', () => {
const NextRoot = require('./containers/Root').default;
render( NextRoot )
})
}
function render ( RootElement ) {
ReactDOM.render(
<AppContainer>
<RootElement/>
</AppContainer>,
document.querySelector('#root')
)
}
containers/Root/index.jsx
import "client/styles/index.scss"
import React from 'react'
import { createStore, applyMiddleware } from 'redux'
import { connect, Provider } from 'react-redux'
import rootReducer from './reducer'
import thunk from 'redux-thunk'
import {
Route,
Router,
IndexRoute,
hashHistory,
} from 'react-router'
import App from 'client/containers/App'
import Index from 'client/containers/Index'
import Learn from 'client/containers/Learn'
import Review from 'client/containers/Review'
import Designer from 'client/containers/Designer'
import Inspector from 'client/containers/Inspector'
const initialState = undefined
export const store = applyMiddleware( thunk )( createStore )( rootReducer, initialState, window.devToolsExtension && window.devToolsExtension() )
const Root = props => {
return (
<Provider store={ store }>
<Router history={ hashHistory }>
<Route path="/" component={ App }>
<IndexRoute component={ Index }/>
<Route path="/learn" component={ Learn }/>
<Route path="/designer" component={ Designer }/>
<Route path="/inspector" component={ Inspector }/>
<Route path="/review" component={ Review }/>
<Route path="*" component={ Index }/>
</Route>
</Router>
</Provider>
)
}
export default Root
Thanks, @thomfoolery. It'd be nice if the author could instead help with Webpack's/our docs instead of Medium articles :smile:
@Q-Man / @mkalish: please open a separate issue with a repository displaying the issue if you're still having the same problem. This issue already has three different people with potentially different problems.
Thanx @thomfoolery, your code helped me to find the problem.
The main reason for my problem was this: I'm using HMR with TypeScript. Because there is no typing for "module.hot" I tried to avoid the TypeScript compile error by writing the HMR replacement code like this:
//NOT WORKING!!!
if (module["hot"]) {
module["hot"].accept('./parts/main', () => {
const NextRoot = require('./parts/main').MainContainer;
render( NextRoot )
})
}
This for some reason this doesn't work. So I changed it to this and now it works:
//WORKING!!!
declare var module; //avoid TypeScript compile error
if (module.hot) {
module.hot.accept('./parts/main', () => {
const NextRoot = require('./parts/main').MainContainer;
render( NextRoot )
})
}
So i've got a very similar issue http://th3fallen.d.pr/4o2K in that video you see the word coworker become coworkers as expected but then the entire application reloads is this similar to what you were seing?
So I'm still having the same issue... In your post @thomfoolery, why are you adding 'webpack/hot/only-dev-server',? It seems it adds a second dev-servers. I can see twice this log in the console with that:
Waiting for update signal from WDS...
I wonder if my initial issue might be related to react-router 3 as well..
How do you make HR works with react router?
@calesce Do you have any example with RR? It looks like most people have issues with that specifically
Any updates on this?
still getting it here, haven't found a fix
@gaearon is there any kind of verbose logging we can enable (via config or source build) that would give us a better idea of why our stacks are insisting on doing full reloads? I just spent two hours trying to isolate the cause and came up with nothing =/ I'm not even sure if react-router has anything to do with it!
EDIT: Update. Sigh. For posterity's sake, here is what I was doing wrong and what I had to fix. I'm using webpack 2, babel, es6, etc in my project.
{devServer: {hot: true}} in my webpack.config.js"presets": [ ["es2015", {"modules": false}] ... ] if (module.hot) {
module.hot.accept('./App.jsx', (App) => { render(App) })
}
when I should've had
if (module.hot) {
module.hot.accept('./App.jsx', () => { render(App) })
}
In the former, I was receiving an array of strings naming the matched component, but using es6 modules I did not need that.
Fundamentally the stupid thing I forgot to do that helped me solve everything was turn on "preserve log" in my console. =/ Per my initial comment, there is, in fact, a wealth of warnings explaining what is wrong if you don't let the console reset on reload.
I am experiencing this, and can echo @tleunen, I am seeing this:
[HMR] Waiting for update signal from WDS... dev-server.js:49
[HMR] Waiting for update signal from WDS... only-dev-server.js:66
[WDS] Hot Module Replacement enabled. client?843a:41
I can't find anything else that's different from what others are doing. I am not using React Router.
my problem was that I put the following code in the component rather than index.js
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
after putting it in index.js problem was gone
I found out by turning on Preserve log in chrome devtools thanks to @sbussetti
@sbussetti your #2 is what was causing my issue, thanks for writing it down. I recommend anyone struggling with this to go to the boiler plate as well and comparing your configuration.
I'm running into this problem with [email protected] too.
Does anyone have a link to configuring HMR with [email protected] and Webpack 3?
Edit: I solved my problem — I was following these docs closely, but not webpack-dev-server's docs closely enough.
It is recommended that
devServer.publicPathis the same asoutput.publicPath.
Setting both devServer.publicPath and output.publicPath to /js/ worked for my configuration (with both 1.3.1 and 3.0-beta).
It should be solved in v4 please give it a try!
Most helpful comment
my problem was that I put the following code in the component rather than
index.jsimport injectTapEventPlugin from 'react-tap-event-plugin'; injectTapEventPlugin();after putting it in
index.jsproblem was goneI found out by turning on
Preserve login chromedevtoolsthanks to @sbussetti