Way to reproduce the issue:
next branch) https://github.com/gaearon/react-hot-boilerplate/tree/nextsrc/HoC.jsimport React, { Component } from 'react';
export function provideHoC() {
return WrappedComponent => {
class HoC extends Component {
render() {
return <WrappedComponent {...this.props} />
}
}
HoC.displayName = (WrappedComponent.displayName || WrappedComponent.name) + 'WithHOC';
return HoC;
};
}
src/Counter.js import React, { Component } from 'react';
+import { provideHoC } from './HoC';
-export default class Counter extends Component {
+class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
}
componentDidMount() {
this.interval = setInterval(this.tick.bind(this), 1000);
}
tick() {
this.setState({ counter: this.state.counter + 1 });
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <h2>Counter: {this.state.counter}</h2>;
}
}
+
+export default provideHoC()(provideHoC()(Counter));
npm start and go to http://localhost:3000.render method of Counter.Due to internal logic, all spare parts (ie hot-replaceable) must be extracted as top-level variables, or HRL will not be able to hot-swap them.
This is a stopper for HoC or decorators. It is just easier to convert HOCs to a normal, prop-based components, and use react, not functional composition, to create target logic.
Or just use
const level1 = provideHoC()(Counter);
const level2 = provideHoC()(level1);
export default level2;
We have to add this to documentation.
@neoziro. Never too late. I'll do it.
@theKashey done in #655
Hard to fix on huge projects with tons of nested HoCs (since it is proper way to do HoCs). I created babel plugin to solve this:
https://www.npmjs.com/package/extract-hoc
@quangbuule - looking quite good, but, please, add tests and a bit more description.
This is good, we could eventually integrate it in the project if it is enough stable.
I added some tests here: https://github.com/quangbuule/extract-hoc/blob/master/test/__snapshots__/babel.test.js.snap
Still running into this issue, even after using extra-hoc babel plugin and manually extracting HoCs into separate components
Package.json: https://github.com/blazing-edge-labs/admin-playground/blob/master/package.json
Component with HoCs: https://github.com/blazing-edge-labs/admin-playground/blob/master/src/modules/Examples/Profile/Edit/index.js
I'm getting the error with this plugin as well.
Also I realised that HOCs cause component state reload now.
@quangbuule could you confirm this part of bug as well? Does your plugin assume to fix state reload bug?
Thank you.
Here are the errors I get:
React Hot Loader: this component is not accepted by Hot Loader.
Please check is it extracted as a top level class, a function or a variable.
Click below to reveal the source location:
Æ’ Connect(props, context) {
_classCallCheck(this, Connect);
var _this = _possibleConstructorReturn(this, _Component.call(this, props, context));
_this.version = version;
…
React Hot Loader: this component is not accepted by Hot Loader.
Please check is it extracted as a top level class, a function or a variable.
Click below to reveal the source location:
Æ’ Form() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, Form);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++)…
@mqklin No, the react-hot-loader is suppose to be better than previous version/library, but from what I see, developing app with react-transform-hmr is much less painful. There are several cases that your code might have and won't work with react-hot-loader. My library is just to solve the case when you used nested HoC wrappers.
It basically convert this (which not work with react-hot-loader):
var FinalComponent = foo()(bar()(TheComponent))
to things like this:
var FinalComponent_arg1 = bar()(TheComponent);
var FinalComponent = foo()(FinalComponent_arg1);
@mateoKaradza - just have a look on your project.
First - you did not wrap your App with HotContainer. Next - there is no errors in console. But state is dropping on update :(
According to your message - you have problems with the internals of redux-form.
@theKashey thanks for taking a look
Here is the HotContainer for the app: https://github.com/blazing-edge-labs/admin-playground/blob/master/src/index.js#L12
There are no errors in the console because I downgraded version of React Hot Loader, latest version was broken for me, I'd get a message in console saying that the component was updated, but it didn't affect loaded app in the browser (any component). I switched to an older version and now it works fine.
Issue with redux-form is with its initialValues prop. After hot reload, the forms gets re-rendered and it doesn't reload initial values. I saw latests PRs and there was a fix where such functionality can be disabled in development mode, looking forward to test it once they release next version.
@mateoKaradza are you expecting redux form to reset values to the initial state on remount? There must be no remount.
Will try to dig your case once again.
PS:
Here is the HotContainer for the app: https://github.com/blazing-edge-labs/admin-playground/blob/master/src/index.js#L12
I still can't see it. You just accept changes.
You have to wrap whole application with AppContainer
import { AppContainer } from 'react-hot-loader'; // <------
const render = Component => {
ReactDOM.render(
<AppContainer> <<--- not exists in your code.
<Component />
</AppContainer>,
document.getElementById('root'),
)
}
Without this component magic will not work.
@quangbuule doest react-transform-hmr work with React16 and decorators?
@mqklin have no idea, my team haven't used the React 16 yet :).
@mqklin I don't think react-transform-hmr works with React 16, but I can't confirm.
@neoziro so, as I understand, I can't use RHL3 with decorators, right? Because state is reset on every hot reload?
@mqklin - as long there is no "decorators" in JS you can try to add babel plugins
ie
"plugins": [
"transform-decorators-legacy",
"extract-hoc/babel",
"react-hot-loader/babel"
]
PS: Might not work. Having no chance to properly test it, sorry.
https://github.com/quangbuule/extract-hoc solved this issue for me for react-apollo and react-redux HOCs. Would be great if this was integrated somehow.
@theKashey @transcranial still React Hot Loader: this component is not accepted by Hot Loader.
Here is a repro project:
https://github.com/mqklin/rhl3-decorators-bug
And a gif:

You can see that state breaks only if I use decorators (I use extract-hoc, doesn't help)
I just tried it with react-transform-hmr and got exactly the same problem (works only without decorators). Here is PR: https://github.com/mqklin/rhl3-decorators-bug/pull/1/files
Decorators will not work at all. There is __no way__ to make them work.
Except #711 - it will literally solve everything. I'll do my best to make v4 sorted out before Christmas.
A long issue finally fixed in React Hot Loader v4.
Most helpful comment
Hard to fix on huge projects with tons of nested HoCs (since it is proper way to do HoCs). I created babel plugin to solve this:
https://www.npmjs.com/package/extract-hoc