-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Reset instance vars before calling commit phase lifecycles #10481
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arguments, slice and apply are all things that are often slow paths. can we do less meta programming and more programming?
dd70c0a
to
834938e
Compare
@sebmarkbage Updated, now with more programming |
@@ -495,6 +499,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>( | |||
if (__DEV__) { | |||
startPhaseTimer(finishedWork, 'componentDidMount'); | |||
} | |||
instance.props = finishedWork.memoizedProps; | |||
instance.state = finishedWork.memoizedState; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any observable way these wouldn't already be the same?
Other than the user setting them themselves? (I suppose if they do, then this is a breaking change now.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that I can think of, more concerned about the case I can't think of, like how I didn't consider error boundaries. Is this a perf concern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can think of some in async mode, just not sync mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about async mode? I can't even think of them there.
@@ -505,6 +511,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>( | |||
if (__DEV__) { | |||
startPhaseTimer(finishedWork, 'componentDidUpdate'); | |||
} | |||
instance.props = finishedWork.memoizedProps; | |||
instance.state = finishedWork.memoizedState; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for didUpdate.
Fixes an issue where if a component throws, its instance variables are not reset before
componentWillUnmount
is called. See https://jsfiddle.net/m3pL3yaj/ for an illustration.To protect against issues like this, we should always set
this.props
andthis.state
right before calling a lifecycle method, as if they were explicit arguments.