{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/react/issues/3234","labels_url":"https://api.github.com/repos/facebook/react/issues/3234/labels{/name}","comments_url":"https://api.github.com/repos/facebook/react/issues/3234/comments","events_url":"https://api.github.com/repos/facebook/react/issues/3234/events","html_url":"https://github.com/facebook/react/issues/3234","id":58520681,"number":3234,"title":"How Should Refs Work?","user":{"login":"sebmarkbage","id":63648,"avatar_url":"https://avatars.githubusercontent.com/u/63648?v=3","gravatar_id":"","url":"https://api.github.com/users/sebmarkbage","html_url":"https://github.com/sebmarkbage","followers_url":"https://api.github.com/users/sebmarkbage/followers","following_url":"https://api.github.com/users/sebmarkbage/following{/other_user}","gists_url":"https://api.github.com/users/sebmarkbage/gists{/gist_id}","starred_url":"https://api.github.com/users/sebmarkbage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebmarkbage/subscriptions","organizations_url":"https://api.github.com/users/sebmarkbage/orgs","repos_url":"https://api.github.com/users/sebmarkbage/repos","events_url":"https://api.github.com/users/sebmarkbage/events{/privacy}","received_events_url":"https://api.github.com/users/sebmarkbage/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/facebook/react/labels/big%20picture","name":"big picture","color":"0052cc"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-02-22T21:38:23Z","updated_at":"2015-11-06T11:53:54Z","closed_at":null,"body":"Spinoff discussion of #1373, #3128 and #3228.\r\n\r\nWe're pretty sure that we need to change the current way refs work (see above). However, the new ref callbacks are also not ideal because it relies on some imperative code and suffers from timing issues like all imperative life-cycles. It is also not very convenient without arrow functions. Even with arrow functions it might suffer from performance issues.\r\n\r\nA few things refs tries to solve:\r\n\r\n- Imperative access to APIs that doesn't have declarative counter-parts yet. E.g. DOM layout.\r\n- Fast-path down the tree to update deeply to by-pass reconciliation. Perf-optimization.\r\n- Get the current state of a child that you don't want to control without duplicating state (which might possibly diverge).\r\n- Send signals/pulses downwards."},"comment":{"url":"https://api.github.com/repos/facebook/react/issues/comments/154392370","html_url":"https://github.com/facebook/react/issues/3234#issuecomment-154392370","issue_url":"https://api.github.com/repos/facebook/react/issues/3234","id":154392370,"user":{"login":"fdecampredon","id":864201,"avatar_url":"https://avatars.githubusercontent.com/u/864201?v=3","gravatar_id":"","url":"https://api.github.com/users/fdecampredon","html_url":"https://github.com/fdecampredon","followers_url":"https://api.github.com/users/fdecampredon/followers","following_url":"https://api.github.com/users/fdecampredon/following{/other_user}","gists_url":"https://api.github.com/users/fdecampredon/gists{/gist_id}","starred_url":"https://api.github.com/users/fdecampredon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fdecampredon/subscriptions","organizations_url":"https://api.github.com/users/fdecampredon/orgs","repos_url":"https://api.github.com/users/fdecampredon/repos","events_url":"https://api.github.com/users/fdecampredon/events{/privacy}","received_events_url":"https://api.github.com/users/fdecampredon/received_events","type":"User","site_admin":false},"created_at":"2015-11-06T11:53:54Z","updated_at":"2015-11-06T11:53:54Z","body":"I have some limitation with the current ref function. \r\nI often use a pattern where I am using ref for some sort of *external controller* that helps me implementing some behaviors on my component. \r\nFor example I have a `DropDownController` which takes a change callback as parameter and exposes 2 refs functions and will control when a dropdown should be open or closed: \r\n\r\n```javascript\r\nclass MyComponent extends React.Component {\r\n  state = { open: false }\r\n  ddc = DropDownController(open => this._onChange(open));\r\n \r\n  _onChange(open)  {\r\n    this.setState({ open });\r\n  }\r\n  \r\n  render() {\r\n   return (\r\n    <div>\r\n      <button ref={this.ddc.openButtonRef}>+</button>\r\n      {this.state.open &&\r\n        <div ref={this.ddc.dropDownRef}>....</div>}\r\n    </div>\r\n  }\r\n}\r\n```\r\nThe controller manually creates event handlers and the dropdown is closed if a click event happen outside of the dropdown.\r\nThat's working fine, but sometimes I would like to use those same refs for multiple elements that should also trigger the dropdown opening, or not triggering the dropdown closing.\r\nUnfortunately if I do so I won't be able to clean my events handler correctly since `ReactRef` doesn't pass  the instance of the component being unmounted when ref are detached.\r\n\r\nOne solution could be that the ref function is invoqued with `null` as first parameter but also the instance of the unmounted component as second parameter.\r\nI monkey patched `ReactRef` to do so and it's working fine, but I would prefer to be able to avoid monkey patch."}}