{"action":"created","issue":{"url":"https://api.github.com/repos/rackt/react-redux/issues/179","labels_url":"https://api.github.com/repos/rackt/react-redux/issues/179/labels{/name}","comments_url":"https://api.github.com/repos/rackt/react-redux/issues/179/comments","events_url":"https://api.github.com/repos/rackt/react-redux/issues/179/events","html_url":"https://github.com/rackt/react-redux/pull/179","id":115753156,"number":179,"title":"Add stateThunk / dispatchThunk options","user":{"login":"tgriesser","id":154748,"avatar_url":"https://avatars.githubusercontent.com/u/154748?v=3","gravatar_id":"","url":"https://api.github.com/users/tgriesser","html_url":"https://github.com/tgriesser","followers_url":"https://api.github.com/users/tgriesser/followers","following_url":"https://api.github.com/users/tgriesser/following{/other_user}","gists_url":"https://api.github.com/users/tgriesser/gists{/gist_id}","starred_url":"https://api.github.com/users/tgriesser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgriesser/subscriptions","organizations_url":"https://api.github.com/users/tgriesser/orgs","repos_url":"https://api.github.com/users/tgriesser/repos","events_url":"https://api.github.com/users/tgriesser/events{/privacy}","received_events_url":"https://api.github.com/users/tgriesser/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2015-11-08T19:16:04Z","updated_at":"2015-11-09T17:46:40Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rackt/react-redux/pulls/179","html_url":"https://github.com/rackt/react-redux/pull/179","diff_url":"https://github.com/rackt/react-redux/pull/179.diff","patch_url":"https://github.com/rackt/react-redux/pull/179.patch"},"body":"Adds two new options, `stateThunk` and `dispatchThunk`. When set to true, it signifies that the value of `mapStateToProps` or `mapDispatchToProps` are thunks, called in the constructor & return values stored on the connected component class.\r\n\r\nThe use case comes from reselect - I noticed that although functions are memoized, when using `props` it destroys the utility of the memoziation feature. The idea here is that each connected component would return a unique memoized selector, rather than sharing one between all instances of a component and ending up with a ton of cache misses.\r\n\r\nSo instead of:\r\n\r\n```js\r\n@connect(createSelector(...fns))\r\n```\r\n\r\nYou'd do:\r\n\r\n```js\r\n@connect(() => createSelector(...fns), null, null, {stateThunk: true})\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/rackt/react-redux/issues/comments/155137376","html_url":"https://github.com/rackt/react-redux/pull/179#issuecomment-155137376","issue_url":"https://api.github.com/repos/rackt/react-redux/issues/179","id":155137376,"user":{"login":"ellbee","id":6018379,"avatar_url":"https://avatars.githubusercontent.com/u/6018379?v=3","gravatar_id":"","url":"https://api.github.com/users/ellbee","html_url":"https://github.com/ellbee","followers_url":"https://api.github.com/users/ellbee/followers","following_url":"https://api.github.com/users/ellbee/following{/other_user}","gists_url":"https://api.github.com/users/ellbee/gists{/gist_id}","starred_url":"https://api.github.com/users/ellbee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ellbee/subscriptions","organizations_url":"https://api.github.com/users/ellbee/orgs","repos_url":"https://api.github.com/users/ellbee/repos","events_url":"https://api.github.com/users/ellbee/events{/privacy}","received_events_url":"https://api.github.com/users/ellbee/received_events","type":"User","site_admin":false},"created_at":"2015-11-09T17:46:40Z","updated_at":"2015-11-09T17:46:40Z","body":"I have checked out the PR, and the approach looks reasonable but I am concerned that the `memoize` HOC in the tests is accessing private `react-redux` API, and I can't currently see how it would work if you don't access private API.\r\n\r\nI was also wondering if we can achieve the same thing without making any changes to `react-redux`? I knocked together the following HOC to be called in place of `connect` that seems to work for a simple test project:\r\n\r\n```js\r\nimport React from 'react'\r\nimport { connect } from 'react-redux'\r\n\r\nexport default function connectWrapper(\r\n  Component,\r\n  mapStateThunk,\r\n  mapDispatchThunk(),\r\n  mergeProps,\r\n  options = {}\r\n) {\r\n  const Wrapped = class extends React.Component {\r\n    constructor() {\r\n      super()\r\n      this.component = connect(\r\n        mapStateThunk(),\r\n        mapDispatchThunk(),\r\n        mergeProps,\r\n        options\r\n      )(Component)\r\n    }\r\n    render() {\r\n      return <this.component {...this.props} {...this.state} />\r\n    }\r\n  }\r\n  Wrapped.displayName = `WrappedConnect(${Component.displayName})`\r\n  return Wrapped\r\n};\r\n```\r\n\r\nAdvantages of the approach above: No changes to `react-redux` needed.\r\nDisadvantages: Creates a new wrapper class for each instantiation of the component\r\n\r\nAdvantages of the PR: Does not create a new wrapper class for each instantiation of the component\r\nDisadvantages: Changes to `react-redux` needed. Still requires a wrapping HOC to be written. Looks like the wrapping HOC needs to use non-public internal `react-redux` API.\r\n\r\n@tgriesser What do you think? Is creating a new wrapper class every time going to be a problem? Have I missed anything?"}}