{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/react/issues/8743","repository_url":"https://api.github.com/repos/facebook/react","labels_url":"https://api.github.com/repos/facebook/react/issues/8743/labels{/name}","comments_url":"https://api.github.com/repos/facebook/react/issues/8743/comments","events_url":"https://api.github.com/repos/facebook/react/issues/8743/events","html_url":"https://github.com/facebook/react/issues/8743","id":199954305,"number":8743,"title":"Expose key for helper libraries","user":{"login":"natew","id":12100,"avatar_url":"https://avatars.githubusercontent.com/u/12100?v=3","gravatar_id":"","url":"https://api.github.com/users/natew","html_url":"https://github.com/natew","followers_url":"https://api.github.com/users/natew/followers","following_url":"https://api.github.com/users/natew/following{/other_user}","gists_url":"https://api.github.com/users/natew/gists{/gist_id}","starred_url":"https://api.github.com/users/natew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natew/subscriptions","organizations_url":"https://api.github.com/users/natew/orgs","repos_url":"https://api.github.com/users/natew/repos","events_url":"https://api.github.com/users/natew/events{/privacy}","received_events_url":"https://api.github.com/users/natew/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2017-01-10T22:41:26Z","updated_at":"2017-01-11T19:32:09Z","closed_at":null,"body":"**Do you want to request a *feature* or report a *bug*?**\r\nFeature\r\n\r\n**What is the current behavior?**\r\nYou can't access this.props.key / this.key\r\n\r\n**What is the expected behavior?**\r\nWe have a use case where we hydrate/dehydrate certain components for an HMR plugin we've developed internally.\r\n\r\nBut, when HMR'ing a file, we often need to access things within loops, and rehydrate the right data.\r\n\r\nRight now, we have to add a secondary key to everything, but this is only for our development tool.\r\n\r\nIf we had access to keys, this would be trivial to implement. It's also *impossible* to implement with a babel compiler trick, because we need to detect these components/loops at runtime, and we can't just add a `secondKey` prop everywhere because we'd have a mess in our props.\r\n\r\nIt seems like it's rather end-user-hostile to not at least give a backdoor into accessing keys, so my proposal, for all the weird edge case uses like our own here, would be to expose:\r\n\r\n```React.getKey()```\r\n\r\nWhich would take a component instance and return the key for it.\r\n\r\nThere could be appropriate warnings around it in documentation and elsewhere."},"comment":{"url":"https://api.github.com/repos/facebook/react/issues/comments/271970218","html_url":"https://github.com/facebook/react/issues/8743#issuecomment-271970218","issue_url":"https://api.github.com/repos/facebook/react/issues/8743","id":271970218,"user":{"login":"natew","id":12100,"avatar_url":"https://avatars.githubusercontent.com/u/12100?v=3","gravatar_id":"","url":"https://api.github.com/users/natew","html_url":"https://github.com/natew","followers_url":"https://api.github.com/users/natew/followers","following_url":"https://api.github.com/users/natew/following{/other_user}","gists_url":"https://api.github.com/users/natew/gists{/gist_id}","starred_url":"https://api.github.com/users/natew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natew/subscriptions","organizations_url":"https://api.github.com/users/natew/orgs","repos_url":"https://api.github.com/users/natew/repos","events_url":"https://api.github.com/users/natew/events{/privacy}","received_events_url":"https://api.github.com/users/natew/received_events","type":"User","site_admin":false},"created_at":"2017-01-11T19:32:09Z","updated_at":"2017-01-11T19:32:09Z","body":"Ok, tried to make this halfway legible, it's extracted and simplified quite a bit. Don't think it compiles, but lmk if it makes sense:\r\n\r\n```js\r\n// attach.js\r\n\r\nlet previousStores = {}\r\n\r\nexport default (fileId, provided, child) => {\r\n  if (module && module.hot) {\r\n    const { stores } = module.hot.data\r\n    previousStores[module.id] = stores[fileId]\r\n  }\r\n\r\n  return class StoreProvider extends Component {\r\n    state = {\r\n      stores: {}\r\n    }\r\n\r\n    componentDidMount() {\r\n      const storesOld = {}\r\n\r\n      // hmr\r\n      if (module && module.hot) {\r\n        // restore\r\n        if (previousStores[module.id]) {\r\n          const previous = previousStores[module.id]\r\n\r\n          Object.assign(storesOld, previous._isKeyed_ ?\r\n            previous[this.props.storeKey]\r\n            previous\r\n          )\r\n        }\r\n        // save\r\n        module.hot.dispose(data => {\r\n          data.stores = {}\r\n\r\n          const storeNames = Object.keys(provided)\r\n\r\n          for (const name of storeNames) {\r\n            const store = this.state.stores[name]\r\n\r\n            // allow restore of storeKey'ed stores\r\n            if (this.props.storeKey) {\r\n              data.stores[name] = data.stores[name] || { _isKeyed_: true }\r\n              data.stores[name][this.props.storeKey] = store\r\n            }\r\n            else {\r\n              data.stores[name] = store\r\n            }\r\n          }\r\n        })\r\n      }\r\n\r\n      // create stores\r\n      storeName.forEach(name => {\r\n        let restoreStore\r\n\r\n        if (storesOld[name]) {\r\n          // restore old instance\r\n          restoreStore = storesOld[name]\r\n        }\r\n        else {\r\n          // create new\r\n          restoreStore = new stores[name](this.props)\r\n        }\r\n\r\n        this.setState({\r\n          stores: { ...this.state.stores, [name]: restoreStore }\r\n        })\r\n      })\r\n    }\r\n\r\n    render() {\r\n      // pass this.state.stores to child\r\n    }\r\n  }\r\n}\r\n\r\n// child.js\r\nimport attach from './attach.js'\r\n\r\nclass Store {\r\n  constructor({ index }) {\r\n    this.index = index\r\n  }\r\n}\r\n\r\nlet Child = attach(\r\n  1,\r\n  { hello: Store },\r\n  ({ stores }) => <div>{stores.hello.index}</div>\r\n)\r\n\r\nlet Parent = () => <div>\r\n  {[1,2,3].map(i => <div key={i} storeKey={i} index={i} />}\r\n</div>\r\n```"}}
{"actor":{"display_login":"natew"}}