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

ComponentWillUnmount should only ever be invoked once #6613

Merged
merged 1 commit into from
Apr 26, 2016

Conversation

jimfb
Copy link
Contributor

@jimfb jimfb commented Apr 25, 2016

ComponentWillUnmount should only ever be invoked once

@jimfb
Copy link
Contributor Author

jimfb commented Apr 25, 2016

@spicyj @sebmarkbage

@sebmarkbage
Copy link
Collaborator

Mostly because we don't have a better idea of whether it is better to just always try/catch or if we can reuse another flag or store where in the tree we left off.

@@ -132,6 +132,9 @@ var ReactCompositeComponentMixin = {

// See ReactUpdates and ReactUpdateQueue.
this._pendingCallbacks = null;

// ComponentWillUnmount shall only be called once
this.calledComponentWillUnmount = false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use underscore for consistency.

@jimfb jimfb force-pushed the componentWillUnmount-once branch from 008058d to a8e64f1 Compare April 25, 2016 20:30

expect(function() {
ReactDOM.render(<App ref={setRef} />, container);
stage = 2;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any reason not to pass stage as a prop to App?

@jimfb jimfb force-pushed the componentWillUnmount-once branch from a8e64f1 to fd43666 Compare April 26, 2016 00:19
@jimfb jimfb added this to the 15.0.x milestone Apr 26, 2016
@jimfb jimfb merged commit 8dfdac6 into facebook:master Apr 26, 2016
zpao pushed a commit that referenced this pull request Apr 28, 2016
@zpao zpao modified the milestones: 15.0.2, 15.0.x Apr 28, 2016
gaearon added a commit that referenced this pull request Oct 15, 2016
* Initial pass at the easy case of updates (updates that start at the root).

* Don't expect an extra componentWillUnmount call

It was fixed in #6613.

* Remove duplicate expectations from the test

* Fix style issues

* Make naming consistent throughout the tests

* receiveComponent() does not accept safely argument

* Assert that lifecycle and refs fire for error message

* Add more tests for mounting

* Do not call componentWillMount twice on error boundary

* Document more of existing behavior in tests

* Do not call componentWillUnmount() when aborting mounting

Previously, we would call componentWillUnmount() safely on the tree whenever we abort mounting it. However this is likely risky because the tree was never mounted in the first place.

People shouldn't hold resources in componentWillMount() so it's safe to say that we can skip componentWillUnmount() if componentDidMount() was never called.

Here, we introduce a new flag. If we abort during mounting, we will not call componentWillUnmount(). However if we abort during an update, it is safe to call componentWillUnmount() because the previous tree has been mounted by now.

* Consistently display error messages in tests

* Add more logging to tests and remove redundant one

* Refactor tests

* Split complicated tests into smaller ones

* Assert clean unmounting

* Add assertions about update hooks

* Add more tests to document existing behavior and remove irrelevant details

* Verify we can recover from error state

* Fix lint

* Error in boundary’s componentWillMount should propagate up

This test is currently failing.

* Move calling componentWillMount() into mountComponent()

This removes the unnecessary non-recursive skipLifecycle check.
It fixes the previously failing test that verifies that if a boundary throws in its own componentWillMount(), the error will propagate.

* Remove extra whitespace
colbyr pushed a commit to HubSpot/general-store that referenced this pull request Mar 6, 2017
It seems that in certain versions of React it was possible for
`componentWillMount` to be called more than once. facebook/react#6613

If that happened to a `connect`ed component, it would cause
`dispatcher.unregister` to be called again with a token that was already
unregistered causing an exception.

This `null`s the token field so unregister can only be called once for a
given token.
colbyr pushed a commit to HubSpot/general-store that referenced this pull request Mar 6, 2017
It seems that in certain versions of React it was possible for
`componentWillMount` to be called more than once. facebook/react#6613

If that happened to a `connect`ed component, it would cause
`dispatcher.unregister` to be called again with a token that was already
unregistered causing an exception.

This `null`s the token field so unregister can only be called once for a
given token.
colbyr added a commit to HubSpot/general-store that referenced this pull request Mar 6, 2017
It seems that in certain versions of React it was possible for
`componentWillMount` to be called more than once. facebook/react#6613

If that happened to a `connect`ed component, it would cause
`dispatcher.unregister` to be called again with a token that was already
unregistered causing an exception.

This `null`s the token field so unregister can only be called once for a
given token.
acusti pushed a commit to brandcast/react that referenced this pull request Mar 15, 2017
* Initial pass at the easy case of updates (updates that start at the root).

* Don't expect an extra componentWillUnmount call

It was fixed in facebook#6613.

* Remove duplicate expectations from the test

* Fix style issues

* Make naming consistent throughout the tests

* receiveComponent() does not accept safely argument

* Assert that lifecycle and refs fire for error message

* Add more tests for mounting

* Do not call componentWillMount twice on error boundary

* Document more of existing behavior in tests

* Do not call componentWillUnmount() when aborting mounting

Previously, we would call componentWillUnmount() safely on the tree whenever we abort mounting it. However this is likely risky because the tree was never mounted in the first place.

People shouldn't hold resources in componentWillMount() so it's safe to say that we can skip componentWillUnmount() if componentDidMount() was never called.

Here, we introduce a new flag. If we abort during mounting, we will not call componentWillUnmount(). However if we abort during an update, it is safe to call componentWillUnmount() because the previous tree has been mounted by now.

* Consistently display error messages in tests

* Add more logging to tests and remove redundant one

* Refactor tests

* Split complicated tests into smaller ones

* Assert clean unmounting

* Add assertions about update hooks

* Add more tests to document existing behavior and remove irrelevant details

* Verify we can recover from error state

* Fix lint

* Error in boundary’s componentWillMount should propagate up

This test is currently failing.

* Move calling componentWillMount() into mountComponent()

This removes the unnecessary non-recursive skipLifecycle check.
It fixes the previously failing test that verifies that if a boundary throws in its own componentWillMount(), the error will propagate.

* Remove extra whitespace
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.

5 participants