Issue 1:
Describe what you were doing when the bug occurred:

1.

2.

3.

Please do not remove the text below this line

DevTools version: 4.10.1-f160547f47

Call stack: at updateTree (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:19702:53)

at getCommitTree (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:19574:26)

at ProfilingCache_ProfilingCache.getCommitTree (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:20115:11)

at CommitFlamegraphAutoSizer (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:34161:33)

at Hh (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:12807:7)

at qi (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:13457:7)

at mk (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:16074:86)

at lk (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:15459:11)

at kk (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:15451:23)

at ck (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:15435:5)

Component stack: at CommitFlamegraphAutoSizer (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:34144:50)

at div

at div

at div

at SettingsModalContextController (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:28206:3)

at Profiler_Profiler (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:35772:50)

at ErrorBoundary_ErrorBoundary (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:29219:5)

at PortaledContent (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:29336:32)

at div

at div

at ProfilerContextController (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:32934:3)

at TreeContextController (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:24322:3)

at SettingsContextController (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:24811:3)

at ModalDialogContextController (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:29404:3)

at DevTools_DevTools (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:36207:3)

Issue 2:
React components could use some way to dynamically add a handler to be called on unmount. Either some event handler like way (this.addUnmountHandler) or some other way to register a 'destructor'/destroy method for an object that a component is holding on to.

componentWillUnmount exists but it does not scale well.

Every time you hold on to something you have to maintain two sections of code, with the cleanup code being separate from the rest of the code.

If you try to cleanup your code using helpers adding the cleanup code could be done in the very same function. But componentWillUnmount doesn't allow that.

Sometimes you end up adding a this._fooSomethingProp to a component you wouldn't normally need, just so that you can hold on to the destructor for use in componentWillUnmount because you can't add the cleanup code in the same closure you set it up in.

Here's one sample use case of mine for unmount handlers.

React is discouraging the use of mixins so I've been trying to move towards alternative patterns in new code. Some helpers only make sense on a component itself and wont work as a special component or a higher-order component.

For some of these needs I've come up with a pattern that involves passing the component to a helper function that will mutate the component and provide some sort of service which is linked to the component.

Two examples from my codebase:

ctxApi provides a component with a version of my internal api which is 'scoped' to the component so that if the component is unmounted all of the api requests' HTTP requests are aborted.

setPending adds a key to a pending state set and returns a pending.cleanup that will unset it, which is intended to be passed to a .finally handler. This pattern provides my buttons, etc... with pending text and spinners while waiting for HTTP requests.

resendConfirmation(email) {
var pending = setPending(this, `${email}:resendConfirmation`);

ctxApi(this)
.then((api) => api.post('/self/resendConfirmationEmail', {email}))
.then(() => alertifyjs.notify("Confirmation message sent"))
.fin(pending.cleanup)
.catch(ignoreAbort)
.catch(notifyOnError)
.done();
}

The problem is that these helpers often need cleanup on unmount. ctxApi needs to abort requests on unmount. And setPending needs to break references so setState isn't called and it doesn't prevent gc. And while I can require that a call to a cleanup function be placed into componentWillUnmount. That is unnecessary boilerplate and easy to forget.

It would be much preferable for these helpers to be able to register an unmount handler on the component instance so they can implicitly clean themselves up.