{"action":"created","issue":{"url":"https://api.github.com/repos/reactjs/rfcs/issues/88","repository_url":"https://api.github.com/repos/reactjs/rfcs","labels_url":"https://api.github.com/repos/reactjs/rfcs/issues/88/labels{/name}","comments_url":"https://api.github.com/repos/reactjs/rfcs/issues/88/comments","events_url":"https://api.github.com/repos/reactjs/rfcs/issues/88/events","html_url":"https://github.com/reactjs/rfcs/issues/88","id":382000971,"node_id":"MDU6SXNzdWUzODIwMDA5NzE=","number":88,"title":"[Hooks] useSharedRef(Symbol)","user":{"login":"xaviergonz","id":6306796,"node_id":"MDQ6VXNlcjYzMDY3OTY=","avatar_url":"https://avatars2.githubusercontent.com/u/6306796?v=4","gravatar_id":"","url":"https://api.github.com/users/xaviergonz","html_url":"https://github.com/xaviergonz","followers_url":"https://api.github.com/users/xaviergonz/followers","following_url":"https://api.github.com/users/xaviergonz/following{/other_user}","gists_url":"https://api.github.com/users/xaviergonz/gists{/gist_id}","starred_url":"https://api.github.com/users/xaviergonz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xaviergonz/subscriptions","organizations_url":"https://api.github.com/users/xaviergonz/orgs","repos_url":"https://api.github.com/users/xaviergonz/repos","events_url":"https://api.github.com/users/xaviergonz/events{/privacy}","received_events_url":"https://api.github.com/users/xaviergonz/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-11-18T21:14:43Z","updated_at":"2018-11-21T22:57:25Z","closed_at":null,"author_association":"NONE","body":"Since hooks are extremely isolated it is impossible to make some hooks act differently depending on if another hook has been previously used on the same component or not.\r\n\r\nWhile this might be easy to pull off when the userland is completely controlled (for example by getting a value from hook 1 and passing it to hook 2) it becomes impossible when it is not.\r\n\r\nImagine this use case (1):\r\n- A library offers two hooks\r\n- They can be used separately, but not together\r\n- There's no way for the hooks to know when this happens\r\n\r\nAnother use case (2):\r\n- A hook is supposed to be used only once per component\r\n- How?\r\n\r\nA way to be able to do this could be using a\r\n```const data = useSharedRef(Symbol)```\r\nWhere the data only is shared *when inside the same component*.\r\n\r\nUse case 1:\r\n```\r\nconst hook1UsedSymbol= new Symbol();\r\nconst hook2UsedSymbol= new Symbol();\r\n\r\nfunction useHook1() {\r\n  const hook1Used = useSharedRef(hook1UsedSymbol);\r\n  const hook2Used = useSharedRef(hook2UsedSymbol);\r\n  useMemo(() => {\r\n    if (hook2Used) {\r\n      throw new Error('hook 1 incompatible with hook 2')\r\n    }\r\n    hook1Used.current = true;\r\n  }, []);\r\n}\r\n\r\nfunction useHook2() {\r\n  const hook1Used = useSharedRef(hook1UsedSymbol);\r\n  const hook2Used = useSharedRef(hook2UsedSymbol);\r\n  useMemo(() => {\r\n    if (hook1Used) {\r\n      throw new Error('hook 2 incompatible with hook 1')\r\n    }\r\n    hook2Used.current = true;\r\n  }, []);\r\n}\r\n```\r\n\r\nUse case 2:\r\n```\r\nconst hookUsedSymbol= new Symbol();\r\n\r\nfunction useHook() {\r\n  const hookUsed = useSharedRef(hookUsedSymbol);\r\n  useMemo(() => {\r\n    if (hookUsed) {\r\n      throw new Error('hook can only be used once')\r\n    }\r\n    hookUsed.current = true;\r\n  }, []);\r\n}\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/reactjs/rfcs/issues/comments/440839515","html_url":"https://github.com/reactjs/rfcs/issues/88#issuecomment-440839515","issue_url":"https://api.github.com/repos/reactjs/rfcs/issues/88","id":440839515,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0MDgzOTUxNQ==","user":{"login":"xaviergonz","id":6306796,"node_id":"MDQ6VXNlcjYzMDY3OTY=","avatar_url":"https://avatars2.githubusercontent.com/u/6306796?v=4","gravatar_id":"","url":"https://api.github.com/users/xaviergonz","html_url":"https://github.com/xaviergonz","followers_url":"https://api.github.com/users/xaviergonz/followers","following_url":"https://api.github.com/users/xaviergonz/following{/other_user}","gists_url":"https://api.github.com/users/xaviergonz/gists{/gist_id}","starred_url":"https://api.github.com/users/xaviergonz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xaviergonz/subscriptions","organizations_url":"https://api.github.com/users/xaviergonz/orgs","repos_url":"https://api.github.com/users/xaviergonz/repos","events_url":"https://api.github.com/users/xaviergonz/events{/privacy}","received_events_url":"https://api.github.com/users/xaviergonz/received_events","type":"User","site_admin":false},"created_at":"2018-11-21T22:57:25Z","updated_at":"2018-11-21T22:57:25Z","author_association":"NONE","body":"Also, this is more geared towards library creators than end users really, and exactly to prevent them from shooting themselves on the foot.\r\n\r\nIn mobx-react-lite for example there is a hook that registers a \"mutation listener / observer\", where registering it more than once only achieves more memory used, some unwanted re-renders and little else, so something like this would allow the library to warn them of such usages in dev mode, but without such hook there's no way to enforce this (AFAIK, maybe I'm missing something)."}}
{"actor":{"display_login":"xaviergonz"}}