-
Notifications
You must be signed in to change notification settings - Fork 801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Methods closure is lost after hot reload #978
Comments
Oh crap :( This is something we could not handle and never will be. As far as I know - RHL should not change the method, if regeneration fails. Are you sure about "lost"? |
It is obvious that RHL calls toString of method to generate REACT_HOT_LOADER_SANDBOX and loses closure of the method Yes, there all right with
By the way, it would be cool to implement the hot method for calling after hot reload of non-component modules:
|
Yeah, I thought about it many many times, as long sometimes it is the only way to solve some complex cases. And it is a super easy thing to do. The main concern against - we probably should be as transparent, as we could. But we are not transparent, and, to be honest, RHL is a one big side effect. @neoziro - what do you thing about |
@theKashey Thanks | Спасибо за оперативные ответы :) |
Ugly working example:
|
Better utilise componentDidUpdate or (even better)componentWillRecieveProps |
I got the same error using |
You will "always" get that error, while you have |
Probably related: #984 Using lodash functions like class MyComponent extends React.Component {
/* other stuff */
parse = _.debounce(() => { parser.parse(this.props.content) });
} will throw a ReferenceError in a function called |
Ok, let's try to find a way, to detect, and repeat functions like this. I could see 2 ways:
ie const constructionLines = () => ({
data: [],
push(a){
this.data.push(a);
a();
}
});
class SomeForm extends React.Component {
constructor() {
super()
this._constructionLines = constructionLines();
this._constructionLines.push(() => this.state = { login: '' }))
this._constructionLines.push(() => this.handle = handle(this))
if (module.hot) {
module.hot.accept('./universal-handler', () => {
this.handle = handle(this)
})
}
} The "problem" - we should not update ALL the properties in constructor, especially state. Calling for a babel Jedi! |
May be I am should not try to solve this, as we solved this problem before
The second approach sounds much more doable, but still - constructors are not "repeatable"(in ES6), and The main problem still the same - we have to get class SomeForm extends React.Component {
constructor() {
super()
this._constructorBody();
}
__constructorBody() { //just extract everything from constructor! (or duplicate)
this.state = { login: '' }
this.handle = handle(this);
}
} Still calling for a babel Jedi! |
Is there a specific reason hot-reloading is so broken for these common React use-cases (i.e. setting instance methods with higher-order-functions)? Is there a way to opt out of hot-reloading methods entirely? Considering my (and probably most people‘s) main use-case for hot reloading is to make small style tweaks, I feel it’s so oblivious to cause components to throw random ReferenceErrors just so component methods aren’t stale. I would gladly reload the page to update my component methods in normal development; I’m not trying to demo a hot-reload tool at a React conference. It looks like there‘s a whole class of bugs besides the ones mentioned here (e.g. #969) caused by not copying over the scope of methods. Maybe a solution might be to put the Sorry for the drive-by complaining, I‘ve just found this bug to be so annoying for the past few days. Don’t have to bandwidth to debug/fix this either 😃 so this probably just comes across as entitled gassing. But if this is new behavior introduced by someone trying to optimize components to be even more hot-reload-y I‘d strongly urge y‘all to roll that baby back cuz it‘s unnecessary and broken. |
The problem is that there is no such thing are hot-reloading in javascript, and we have to emulate it. |
I think I also ran into this problem with my lifecycle visualizer. I'll include the code, so you have another example. I use an HOC that passes a closure as a prop to the wrapped component, more or less like this: export const wrap = (ComponentToWrap) => {
return class Wrapper extends React.Component {
constructor(props) {
super(props);
const x = 42;
this.SFC = () => <div>{x}</div>;
}
render() {
return <ComponentToWrap SFC={this.SFC}/>;
}
}
}; When editing the wrapped component, this fails on a hot reload with:
The problem was introduced by PR #950. Before that, editing the wrapped component was no problem, and when editing the HOC, changes to |
From 4.1.3 up to at least 4.2.0, hot reload fails with a reference error for const `instanceId` in `WrappedLifecyclePanel` and `this.trace` definitions. See issue gaearon/react-hot-loader#978
Going first to "fix" RHL, "back to 4.1.2" behavior (just dont fall), then - implement a new way to update component properties. |
There are several forms in my project. So I created a generic input change handler:
And I use it like this:
First everything goes well. But after a hot reload, when I start typing to the input, I get an
error:
Because the context is lost:
The text was updated successfully, but these errors were encountered: