Skip to content
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

Merged
merged 1 commit into from
Aug 17, 2017

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Aug 17, 2017

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 and this.state right before calling a lifecycle method, as if they were explicit arguments.

Copy link
Collaborator

@sebmarkbage sebmarkbage left a 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?

@acdlite
Copy link
Collaborator Author

acdlite commented Aug 17, 2017

@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;
Copy link
Collaborator

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.)

Copy link
Collaborator Author

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for didUpdate.

@acdlite acdlite merged commit caaa0b0 into facebook:master Aug 17, 2017
@bvaughn bvaughn mentioned this pull request Sep 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants