{"action":"created","issue":{"url":"https://api.github.com/repos/facebookincubator/redux-react-hook/issues/12","repository_url":"https://api.github.com/repos/facebookincubator/redux-react-hook","labels_url":"https://api.github.com/repos/facebookincubator/redux-react-hook/issues/12/labels{/name}","comments_url":"https://api.github.com/repos/facebookincubator/redux-react-hook/issues/12/comments","events_url":"https://api.github.com/repos/facebookincubator/redux-react-hook/issues/12/events","html_url":"https://github.com/facebookincubator/redux-react-hook/issues/12","id":395372073,"node_id":"MDU6SXNzdWUzOTUzNzIwNzM=","number":12,"title":"Investigate use of multiple useMappedState calls","user":{"login":"ncphillips","id":824015,"node_id":"MDQ6VXNlcjgyNDAxNQ==","avatar_url":"https://avatars2.githubusercontent.com/u/824015?v=4","gravatar_id":"","url":"https://api.github.com/users/ncphillips","html_url":"https://github.com/ncphillips","followers_url":"https://api.github.com/users/ncphillips/followers","following_url":"https://api.github.com/users/ncphillips/following{/other_user}","gists_url":"https://api.github.com/users/ncphillips/gists{/gist_id}","starred_url":"https://api.github.com/users/ncphillips/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ncphillips/subscriptions","organizations_url":"https://api.github.com/users/ncphillips/orgs","repos_url":"https://api.github.com/users/ncphillips/repos","events_url":"https://api.github.com/users/ncphillips/events{/privacy}","received_events_url":"https://api.github.com/users/ncphillips/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2019-01-02T20:36:12Z","updated_at":"2019-01-04T04:41:45Z","closed_at":null,"author_association":"NONE","body":"The following note is in the README:\r\n\r\n> NOTE: You should only call useMappedState once per component, in the same way that you'd use connect from react-redux only once per component. Otherwise the component will have multiple store subscriptions and could rerender multiple times from a single store update.\r\n\r\nI think this is a serious downside. One of the main benefits I would hope to get from using hooks with redux, is the ability to create a higher level abstraction. The purpose of doing this would be to hide the details of how my state is managed (i.e. that redux is used at all).\r\n\r\nIn the following example there are two custom hooks that use `redux-react-hook` under the hood. The actual component has no knowledge of Redux at all, it works entirely within its domain.\r\n\r\n```javascript\r\n//\r\n// Individual components\r\n//\r\nimport {useDispatch, useMappedState} from 'redux-react-hook';\r\n\r\nexport function DeleteButton({index}) {\r\n  let todo = useTodo(index)\r\n  let user = useUser()\r\n  \r\n  return (\r\n    <button \r\n      disabled={user.permissions.deleteTodos && !todo.canDelete} \r\n      onClick={todo.deleteTodo}\r\n    >\r\n      Delete {todo.name}\r\n    </button>\r\n  );\r\n}\r\n\r\nfunction useTodo(index) {\r\n  const mapState = useCallback(\r\n    state => ({\r\n      canDelete: state.todos[index].canDelete,\r\n      name: state.todos[index].name,\r\n    }),\r\n    [index],\r\n  );\r\n\r\n  const {canDelete, name} = useMappedState(mapState);\r\n\r\n  const dispatch = useDispatch();\r\n  const deleteTodo = useCallback(\r\n    () =>\r\n      dispatch({\r\n        type: 'delete todo',\r\n        index,\r\n      }),\r\n    [index],\r\n  );\r\n\r\n  return { name, canDelete, deleteTodo }\r\n}\r\n\r\nfunction useUser() {\r\n  const mapState = useCallback(\r\n    state => ({ user: state.user }),\r\n    [],\r\n  );\r\n\r\n  const { user } = useMappedState(mapState);\r\n\r\n  return user\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/facebookincubator/redux-react-hook/issues/comments/451352336","html_url":"https://github.com/facebookincubator/redux-react-hook/issues/12#issuecomment-451352336","issue_url":"https://api.github.com/repos/facebookincubator/redux-react-hook/issues/12","id":451352336,"node_id":"MDEyOklzc3VlQ29tbWVudDQ1MTM1MjMzNg==","user":{"login":"ianobermiller","id":897931,"node_id":"MDQ6VXNlcjg5NzkzMQ==","avatar_url":"https://avatars0.githubusercontent.com/u/897931?v=4","gravatar_id":"","url":"https://api.github.com/users/ianobermiller","html_url":"https://github.com/ianobermiller","followers_url":"https://api.github.com/users/ianobermiller/followers","following_url":"https://api.github.com/users/ianobermiller/following{/other_user}","gists_url":"https://api.github.com/users/ianobermiller/gists{/gist_id}","starred_url":"https://api.github.com/users/ianobermiller/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ianobermiller/subscriptions","organizations_url":"https://api.github.com/users/ianobermiller/orgs","repos_url":"https://api.github.com/users/ianobermiller/repos","events_url":"https://api.github.com/users/ianobermiller/events{/privacy}","received_events_url":"https://api.github.com/users/ianobermiller/received_events","type":"User","site_admin":false},"created_at":"2019-01-04T04:41:45Z","updated_at":"2019-01-04T04:41:45Z","author_association":"CONTRIBUTOR","body":"> It looks like a useMappedState does not cause the component to re-render on each store update\r\n\r\nThat is correct, it does a shallow comparison just like react-redux. There aren't any issues if you were to subscribe to the same data multiple times, because the previous mapped value that is capture is done for each subscription. It would be a little weird, however, to do a shallow comparison on something that isn't expected to be an object (you'd probably want to use an exact comparison instead).\r\n\r\nI did a small test in this codesandbox, https://codesandbox.io/s/7w16rv9x91, see `TodoList.tsx`. In it, I call `useMappedState` twice (so it will do two store subscriptions. If you look at the console logs, however, the component is only rendered once for each store change. This is likely because redux is calling all the subscribers synchronously and React debounces multiple setState calls in the same frame. So at least from a component perf perspective this isn't an issue. The only thing would be to measure the impact of more store subscriptions on Redux, but I am inclined to say that performance-wise this won't be a huge deal.\r\n\r\n"}}
{"actor":{"display_login":"ianobermiller"}}