Skip to content

ComponentWillUnmount should only ever be invoked once - #6613

Merged
jimfb merged 1 commit into
react:masterfrom
jimfb:componentWillUnmount-once
Apr 26, 2016
Merged

jimfb merged 1 commit into
react:masterfrom
jimfb:componentWillUnmount-once

Conversation

@jimfb

@jimfb jimfb commented Apr 25, 2016

Copy link
Copy Markdown
Contributor

ComponentWillUnmount should only ever be invoked once

@jimfb

jimfb commented Apr 25, 2016

Copy link
Copy Markdown
Contributor Author

@spicyj @sebmarkbage

@sebmarkbage

Copy link
Copy Markdown
Contributor

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.

this._pendingCallbacks = null;

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
Contributor

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 react: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. react/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. react/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. react/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 react#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
mrizwanashiq pushed a commit to mrizwanashiq/react that referenced this pull request Jun 25, 2026
mrizwanashiq pushed a commit to mrizwanashiq/react that referenced this pull request Jun 25, 2026
* 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 react#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