{"action":"created","issue":{"url":"https://api.github.com/repos/Automattic/wp-calypso/issues/840","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/840/labels{/name}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/840/comments","events_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/840/events","html_url":"https://github.com/Automattic/wp-calypso/pull/840","id":119029135,"number":840,"title":"Themes: Switch data fetching to Redux","user":{"login":"ockham","id":96308,"avatar_url":"https://avatars.githubusercontent.com/u/96308?v=3","gravatar_id":"","url":"https://api.github.com/users/ockham","html_url":"https://github.com/ockham","followers_url":"https://api.github.com/users/ockham/followers","following_url":"https://api.github.com/users/ockham/following{/other_user}","gists_url":"https://api.github.com/users/ockham/gists{/gist_id}","starred_url":"https://api.github.com/users/ockham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ockham/subscriptions","organizations_url":"https://api.github.com/users/ockham/orgs","repos_url":"https://api.github.com/users/ockham/repos","events_url":"https://api.github.com/users/ockham/events{/privacy}","received_events_url":"https://api.github.com/users/ockham/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Automattic/wp-calypso/labels/Server%20Side%20Rendering","name":"Server Side Rendering","color":"006b75"},{"url":"https://api.github.com/repos/Automattic/wp-calypso/labels/Themes","name":"Themes","color":"006b75"},{"url":"https://api.github.com/repos/Automattic/wp-calypso/labels/[Status]%20In%20Progress","name":"[Status] In Progress","color":"207de5"},{"url":"https://api.github.com/repos/Automattic/wp-calypso/labels/[Status]%20Needs%20Review","name":"[Status] Needs Review","color":"fbca04"}],"state":"open","locked":false,"assignee":{"login":"mcsf","id":150562,"avatar_url":"https://avatars.githubusercontent.com/u/150562?v=3","gravatar_id":"","url":"https://api.github.com/users/mcsf","html_url":"https://github.com/mcsf","followers_url":"https://api.github.com/users/mcsf/followers","following_url":"https://api.github.com/users/mcsf/following{/other_user}","gists_url":"https://api.github.com/users/mcsf/gists{/gist_id}","starred_url":"https://api.github.com/users/mcsf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcsf/subscriptions","organizations_url":"https://api.github.com/users/mcsf/orgs","repos_url":"https://api.github.com/users/mcsf/repos","events_url":"https://api.github.com/users/mcsf/events{/privacy}","received_events_url":"https://api.github.com/users/mcsf/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/Automattic/wp-calypso/milestones/19","html_url":"https://github.com/Automattic/wp-calypso/milestones/Themes:%20Showcase%20M3-LoggedOut","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/milestones/19/labels","id":1420000,"number":19,"title":"Themes: Showcase M3-LoggedOut","description":"","creator":{"login":"hoverduck","id":7233112,"avatar_url":"https://avatars.githubusercontent.com/u/7233112?v=3","gravatar_id":"","url":"https://api.github.com/users/hoverduck","html_url":"https://github.com/hoverduck","followers_url":"https://api.github.com/users/hoverduck/followers","following_url":"https://api.github.com/users/hoverduck/following{/other_user}","gists_url":"https://api.github.com/users/hoverduck/gists{/gist_id}","starred_url":"https://api.github.com/users/hoverduck/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hoverduck/subscriptions","organizations_url":"https://api.github.com/users/hoverduck/orgs","repos_url":"https://api.github.com/users/hoverduck/repos","events_url":"https://api.github.com/users/hoverduck/events{/privacy}","received_events_url":"https://api.github.com/users/hoverduck/received_events","type":"User","site_admin":false},"open_issues":21,"closed_issues":3,"state":"open","created_at":"2015-11-19T15:18:52Z","updated_at":"2015-12-08T11:30:04Z","due_on":"2015-12-09T03:00:00Z","closed_at":null},"comments":22,"created_at":"2015-11-26T11:43:41Z","updated_at":"2015-12-09T06:39:36Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/840","html_url":"https://github.com/Automattic/wp-calypso/pull/840","diff_url":"https://github.com/Automattic/wp-calypso/pull/840.diff","patch_url":"https://github.com/Automattic/wp-calypso/pull/840.patch"},"body":"_Notes by @mcsf:_\r\n\r\n### Context\r\n\r\nWhat started as an experimental branch for a number of Redux-related changes across Themes coalesced into a substantial refactor of `themes-list-fetcher`, a data fetching component which is now Redux-`connect`ed.\r\n\r\n### Decisions\r\n\r\n- `ThemesListFetcher` is kept as a generic data component that relays application state to its children.\r\n- Selectors are given much greater importance, as they allow us to simplify the data model by avoiding forms of data duplication — notably, avoiding storage of derived data next to essential data.\r\n- Use of selectors allowed to altogether eliminate one action: `SEARCH_THEMES`, which was basically a _virtual_ action (read: _hack_) to trigger client-side filtering of themes, a feature specific to Jetpack sites.\r\n\r\n### Next\r\n\r\n- Other smaller Themes-related data components will go the same route as `ThemesListFetcher`.\r\n- As we progress, more derived data should be able to be eliminated from the global state's `themes` branch.\r\n- Some features of the Showcase invoke non-Themes action creators (namely, purchases and customization). It would be conceivable to have a layer of Redux middleware that dispatches certain actions to the singleton Flux architecture.\r\n- Memoization of selectors is something very useful to have, and trivial to implement thanks to immutability. However, there are *server-side-rendering*-specific concerns; specifically:\r\n  * To avoid user-specific data leakage between Node requests, most memoized selectors would have to be bound to a particular request and be GC'd afterwards. This would work the same way that our global Redux store on the server is always bound to a request.\r\n  * For performance improvements, it could be very advantageous that some non-user-specific selectors were capable of cross-request memoization, though care should be given to ensure said selectors's memory usage doesn't grow unintentionally.\r\n\r\n### Bugs\r\n\r\n- [ ] Jetpack sites: searching refetches the themes list when it doesn't need to, though this only happens for the first search.\r\n- [ ] Jetpack sites: searching blurs the search field.\r\n\r\n### Testing\r\n\r\nQA should focus around navigation of the Showcase, switching between sites, including both WP.com and Jetpack sites, searching, per-tier filtering, triggering `InfiniteList`'s fetching, and switching between Showcase and other sections."},"comment":{"url":"https://api.github.com/repos/Automattic/wp-calypso/issues/comments/163130588","html_url":"https://github.com/Automattic/wp-calypso/pull/840#issuecomment-163130588","issue_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/840","id":163130588,"user":{"login":"mcsf","id":150562,"avatar_url":"https://avatars.githubusercontent.com/u/150562?v=3","gravatar_id":"","url":"https://api.github.com/users/mcsf","html_url":"https://github.com/mcsf","followers_url":"https://api.github.com/users/mcsf/followers","following_url":"https://api.github.com/users/mcsf/following{/other_user}","gists_url":"https://api.github.com/users/mcsf/gists{/gist_id}","starred_url":"https://api.github.com/users/mcsf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcsf/subscriptions","organizations_url":"https://api.github.com/users/mcsf/orgs","repos_url":"https://api.github.com/users/mcsf/repos","events_url":"https://api.github.com/users/mcsf/events{/privacy}","received_events_url":"https://api.github.com/users/mcsf/received_events","type":"User","site_admin":false},"created_at":"2015-12-09T06:39:36Z","updated_at":"2015-12-09T06:39:36Z","body":"> Noting that the isJetpack() call inside the themes-list reducer is still causing a bit of trouble.\r\n\r\nOh? But `isJetpack` should be available as an action param — _cf_ [receive action](https://github.com/Automattic/wp-calypso/pull/840/files#diff-22104692e1a08563a6558230f3d10614R104) — so no need to use (and retrofit) selectors inside the reducer, right?"}}