{"action":"opened","issue":{"url":"https://api.github.com/repos/facebook/react/issues/5765","labels_url":"https://api.github.com/repos/facebook/react/issues/5765/labels{/name}","comments_url":"https://api.github.com/repos/facebook/react/issues/5765/comments","events_url":"https://api.github.com/repos/facebook/react/issues/5765/events","html_url":"https://github.com/facebook/react/issues/5765","id":124545647,"number":5765,"title":"Dynamically added unmount handlers","user":{"login":"dantman","id":53399,"avatar_url":"https://avatars.githubusercontent.com/u/53399?v=3","gravatar_id":"","url":"https://api.github.com/users/dantman","html_url":"https://github.com/dantman","followers_url":"https://api.github.com/users/dantman/followers","following_url":"https://api.github.com/users/dantman/following{/other_user}","gists_url":"https://api.github.com/users/dantman/gists{/gist_id}","starred_url":"https://api.github.com/users/dantman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dantman/subscriptions","organizations_url":"https://api.github.com/users/dantman/orgs","repos_url":"https://api.github.com/users/dantman/repos","events_url":"https://api.github.com/users/dantman/events{/privacy}","received_events_url":"https://api.github.com/users/dantman/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-01-01T13:59:20Z","updated_at":"2016-01-01T13:59:20Z","closed_at":null,"body":"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.\r\n\r\n`componentWillUnmount` exists but it does not scale well.\r\n\r\n* 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.\r\n* 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.\r\n* 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.\r\n\r\n----\r\n\r\nHere's one sample use case of mine for unmount handlers.\r\n\r\nReact 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.\r\n\r\nFor 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.\r\n\r\nTwo examples from my codebase:\r\n\r\n`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.\r\n\r\n`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.\r\n\r\n```js\r\nresendConfirmation(email) {\r\n\tvar pending = setPending(this, `${email}:resendConfirmation`);\r\n\r\n\tctxApi(this)\r\n\t\t.then((api) => api.post('/self/resendConfirmationEmail', {email}))\r\n\t\t.then(() => alertifyjs.notify(\"Confirmation message sent\"))\r\n\t\t.fin(pending.cleanup)\r\n\t\t.catch(ignoreAbort)\r\n\t\t.catch(notifyOnError)\r\n\t\t.done();\r\n}\r\n```\r\n\r\nThe 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.\r\n\r\nIt 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."}}