Commit ea09632a authored by Robert Knight's avatar Robert Knight

Make group selectors more efficient

Ensure that selectors for getting the "My groups", "Currently viewing
groups" and "Featured groups" lists only recompute when the groups state
changes. Previously they would have recomputed when _any_ part of the state changed.

More generally, we should be using `createSelector` rather than
`memoize` whenever we have a place in the app that needs to extract a subset
of data from some larger structure and derive some data from that.
parent d0ab6158
......@@ -101,6 +101,7 @@
"redux": "^4.0.1",
"redux-thunk": "^2.1.0",
"request": "^2.76.0",
"reselect": "^4.0.0",
"retry": "^0.12.0",
"scroll-into-view": "^1.8.2",
"seamless-immutable": "^7.1.4",
......
'use strict';
const { createSelector } = require('reselect');
const util = require('../util');
const memoize = require('../../util/memoize');
const { selectors: sessionSelectors } = require('./session');
const { isLoggedIn } = sessionSelectors;
......@@ -126,37 +127,44 @@ function getGroup(state, id) {
*
* @return {Group[]}
*/
const getMyGroups = memoize(state => {
// If logged out, the Public group still has isMember set to true so only
// return groups with membership in logged in state.
if (isLoggedIn(state)) {
return state.groups.filter(g => g.isMember);
const getMyGroups = createSelector(
state => state.groups,
isLoggedIn,
(groups, loggedIn) => {
// If logged out, the Public group still has isMember set to true so only
// return groups with membership in logged in state.
if (loggedIn) {
return groups.filter(g => g.isMember);
}
return [];
}
return [];
});
);
/**
* Return groups the user isn't a member of that are scoped to the URI.
*
* @return {Group[]}
*/
const getFeaturedGroups = memoize(state => {
return state.groups.filter(group => !group.isMember && group.isScopedToUri);
});
const getFeaturedGroups = createSelector(
state => state.groups,
groups => groups.filter(group => !group.isMember && group.isScopedToUri)
);
/**
* Return groups that don't show up in Featured and My Groups.
*
* @return {Group[]}
*/
const getCurrentlyViewingGroups = memoize(state => {
const myGroups = getMyGroups(state);
const featuredGroups = getFeaturedGroups(state);
return state.groups.filter(
g => !myGroups.includes(g) && !featuredGroups.includes(g)
);
});
const getCurrentlyViewingGroups = createSelector(
allGroups,
getMyGroups,
getFeaturedGroups,
(allGroups, myGroups, featuredGroups) => {
return allGroups.filter(
g => !myGroups.includes(g) && !featuredGroups.includes(g)
);
}
);
/**
* Return groups that are scoped to the uri. This is used to return the groups
......@@ -165,9 +173,10 @@ const getCurrentlyViewingGroups = memoize(state => {
*
* @return {Group[]}
*/
const getInScopeGroups = memoize(state => {
return state.groups.filter(g => g.isScopedToUri);
});
const getInScopeGroups = createSelector(
state => state.groups,
groups => groups.filter(g => g.isScopedToUri)
);
module.exports = {
init,
......
......@@ -8431,6 +8431,11 @@ requires-port@^1.0.0:
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
reselect@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
resolve-dir@^1.0.0, resolve-dir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment