When RHL3, I am seeing this warning when files are updated:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the OverviewHeader component.
This is happening because I have a function which calls setState in componentDidMount. However, the component's componentDidMount is called twice; meaning that setState can be called when a component is unmounted.
I would expect componentDidMount to be called once after hot reloading.
`componentDidMount is called twice.
React Hot Loader version:
Run these commands in the project folder and fill in their results:
node -v: v6.9.1Then, specify:
The project I am on is huge; and creating a reproducible demo would take a couple hours. So here are my config options. If this proves unhelpful, I will spend more time to try and create one. My goal is to see if anyone else has experienced this issue, and if anyone has fixed this before.
Things to note:
'use strict';
const _ = require('lodash');
const baseConfig = require('./base');
const path = require('path');
const webpack = require('webpack');
const SassLintPlugin = require('sasslint-webpack-plugin');
const host = '0.0.0.0';
const port = 8000;
const config = _.assign(baseConfig, {
entry: {
app: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://local.tryadhawk.com:8000/',
'webpack/hot/only-dev-server',
'./src/components/RunThePower.tsx',
],
},
output: {
path: path.resolve(__dirname, '..', '..', 'dist', 'the-power', 'assets'),
filename: '[name].js',
publicPath: 'http://' + host + ':' + port + '/assets/',
},
cache: true,
devtool: 'cheap-module-inline-source-map',
devServer: {
contentBase: path.resolve(__dirname, '..', '..', 'src'),
},
plugins: [
...baseConfig.plugins,
new SassLintPlugin({
context: './src/styles/',
configFile: path.resolve(__dirname, '..', 'sass-lint.yml'),
ignoreFiles: [
'./src/styles/signin/SigninForm.scss',
'./src/styles/App.scss',
'./src/styles/tips/TipsEmptyState.scss',
'./src/styles/dashboard/DateRangePicker.scss',
'./src/styles/LoadingScreen/LoadingScreenComponent.scss',
],
}),
new webpack.ProvidePlugin({
Promise: 'imports-loader?this=>global!exports-loader?global.Promise!bluebird',
}),
new webpack.DllReferencePlugin({
context: path.resolve(__dirname, '..', '..'),
manifest: require(path.resolve(__dirname, '..', '..', '.tmp', 'dll', 'vendor-manifest.json')),
}),
new webpack.DefinePlugin({
__DEV__: true,
__SLINGSHOT_DEV__: process.env.SLINGSHOT_DEV ? true : false,
'process.env': { NODE_ENV: JSON.stringify('development') },
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.NamedModulesPlugin()
],
});
config.module.loaders = baseConfig.module.loaders.concat([
{
test: /\.tsx$/,
loaders: ['react-hot-loader/webpack', 'awesome-typescript-loader'],
include: path.resolve(__dirname, '..', '..', 'src'),
},
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader'],
include: path.resolve(__dirname, '..', '..', 'src'),
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap'],
},
]);
module.exports = config;
ReactDOM.render(
<AppContainer>
<Root />
</AppContainer>,
document.getElementById('app')
);
declare const module: any;
if (module.hot) {
module.hot.accept('./../containers/Root', () => {
const NextApp = require('./../containers/Root').default;
ReactDOM.render(
<AppContainer>
<NextApp />
</AppContainer>,
document.getElementById('app')
);
});
}
Same problem
Win10 x64
I just ran into this same problem today as well, but I don't think it is actually the fault of RHL. It only seems to occur when RHL tries to update a module and is unable to do so. It does produce a warning stating something to that affect. Once that happens, calls to methods of React.Component start to produce errors similar to those reported by @ianks. If I perform a full refresh of the browser, forcing a proper update of the modules reporting the errors, the errors go away and everything then works as expected.
The follow up then is, what would prevent RHL from being able to being able to update a module and what should I be doing in order to make sure my components don't choke RHL?
More info: upon closer inspection, the issue is limited to methods called on a ref that is a pointer to a component that has been unmounted by RHL. It appears that assigning a ref to a variable results in a pointer to the original component before it has been wrapped by RHL. After an update, the variable now points to an unmounted component and calling any of its methods that could result in a re-rendering produce an error message and the expected re-rendering does not take place. Here is a sample error:
Warning: forceUpdate(...): Can only update a mounted or mounting component. This usually means you called forceUpdate() on an unmounted component. This is a no-op. Please check the code for the ImpulseGraph component.
@ianks : this is not a problem with RHL, you are stepping on your own feet here and causing this to happen. The docs for componentDidMount() :
Setting state in this method will trigger a re-rendering.
https://facebook.github.io/react/docs/react-component.html#componentdidmount
Move any setState() that you are doing in componentDidMount() to the constructor of your component class and that should make your problem go away.
BTW, you probably want to review your webpack config. It seems to contain a number of errors as well.
Move any setState() that you are doing in componentDidMount() to the constructor of your component class and that should make your problem go away.
This will cause another re-rendering (which is fine), it should not trigger a re-_mount_.
I am having a similar issue but dont do setState in the component. When I have the 'react-hot-loader/babel' preset set any of my onMouseEnters that trigger a setState will create this error. Commenting it out fixes it .
I just run into the same Can only update a mounted or mounting component. warning but I'm not doing any setState calls in componentDidMount. For me the error occurred after I removed transform-es2015-classes from my Babel plugins (so that I'm not outputting full ES6 classes).
The error was caused by the fact that I still had react-hot-loader/babel in my Babel configuration which appears to be only needed if you're transpiling ES2015 classes. After I removed react-hot-loader/babel from my Babel config -- the error went away.
Not sure if this is the same problem as you're having -- but thought I'd share in case others run into this.
I also go the setState error with webpack & typescript. I noticed removing the "react-hot-loader/patch" from my webpack entry stopped the error.
If your using typescript and changing the tsconfig.json compilerOptions -> target to es5 seems to workaround the error aswell.
Same issue, move setState to constructor did not work
@Meeeeow You should not be calling setState in a constructor. Instead, you should just set a value for the state property in the usual way:
export class MyComponent extends React.Component<MyComponentProps, MyComponentState> {
constructor(props: MyComponentProps) {
super(props);
this.state = {
// whatever is required for your component's state
};
}
}
@mutsys
You says:
Move any setState() that you are doing in componentDidMount() to the constructor of your component class and that should make your problem go away.
My component will send XHR request to load data and set loading status in state, i should use this.state = {} in constructor or place setState to somewhere else?
@impaler Thank you! I was in a same situation but solved by removing the "react-hot-loader/patch" from entry.
I also go the setState error with webpack & typescript. I noticed removing the "react-hot-loader/patch" from my webpack entry stopped the error.
If your using typescript and changing the tsconfig.json compilerOptions -> target to es5 seems to workaround the error aswell.
I had this issue when trying to switch from babel-preset-es2015 to babel-preset-env. Adding transform-es2015-classes to the included transforms resolved it for me:
presets: [
['env', {
targets: {
chrome: 60
},
include: ['transform-es2015-classes']
}],
'stage-1',
'react'
],
plugins: ['react-hot-loader/babel']
This is completely solved in React Hot Loader v4.
Most helpful comment
I just run into the same
Can only update a mounted or mounting component.warning but I'm not doing anysetStatecalls incomponentDidMount. For me the error occurred after I removedtransform-es2015-classesfrom my Babel plugins (so that I'm not outputting full ES6 classes).The error was caused by the fact that I still had
react-hot-loader/babelin my Babel configuration which appears to be only needed if you're transpiling ES2015 classes. After I removedreact-hot-loader/babelfrom my Babel config -- the error went away.Not sure if this is the same problem as you're having -- but thought I'd share in case others run into this.