Fix memo: selectMyChannelClaims, selectActiveChannelClaim

## Issue
These should never recalculate after `channel_list` has been fetched, but they do because of poor selector dependency.

## Change
With the `byId` changes from the previous commit, we are now able to memoize these selectors correctly.
This commit is contained in:
infinite-persistence 2021-11-08 19:01:52 +08:00
parent 0736723200
commit 07750bfb4c
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
2 changed files with 21 additions and 11 deletions

View file

@ -1,5 +1,5 @@
import { createSelector } from 'reselect';
import { selectClaimsById, selectMyChannelClaims, makeSelectStakedLevelForChannelUri } from 'redux/selectors/claims';
import { selectClaimWithId, selectMyChannelClaims, makeSelectStakedLevelForChannelUri } from 'redux/selectors/claims';
export const selectState = (state) => state.app || {};
@ -70,15 +70,13 @@ export const selectSplashAnimationEnabled = (state) => selectState(state).splash
export const selectActiveChannelId = (state) => selectState(state).activeChannel;
export const selectActiveChannelClaim = createSelector(
selectActiveChannelId,
selectClaimsById,
(state) => selectClaimWithId(state, selectActiveChannelId(state)), // i.e. 'byId[activeChannelId]' specifically, instead of just 'byId'.
selectMyChannelClaims,
(activeChannelClaimId, claimsById, myChannelClaims) => {
if (!activeChannelClaimId || !claimsById || !myChannelClaims || !myChannelClaims.length) {
(activeChannelClaim, myChannelClaims) => {
if (!activeChannelClaim || !myChannelClaims || !myChannelClaims.length) {
return undefined;
}
const activeChannelClaim = claimsById[activeChannelClaimId];
if (activeChannelClaim) {
return activeChannelClaim;
}

View file

@ -419,14 +419,26 @@ export const selectFetchingMyCollections = (state: State) => selectState(state).
export const selectMyChannelClaimIds = (state: State) => selectState(state).myChannelClaims;
export const selectMyChannelClaims = createSelector(selectState, selectClaimsById, (state, byId) => {
const ids = state.myChannelClaims;
if (!ids) {
return ids;
export const selectMyChannelClaims = createSelector(selectMyChannelClaimIds, (myChannelClaimIds) => {
if (!myChannelClaimIds) {
return myChannelClaimIds;
}
if (!window || !window.store) {
return undefined;
}
// Note: Grabbing the store and running the selector this way is anti-pattern,
// but it is _needed_ and works only because we know for sure that 'byId[]'
// will be populated with the same claims as when 'myChannelClaimIds' is populated.
// If we put 'state' or 'byId' as the input selector, it essentially
// recalculates every time. Putting 'state' as input to createSelector() is
// always wrong from a memoization standpoint.
const state = window.store.getState();
const byId = selectClaimsById(state);
const claims = [];
ids.forEach((id) => {
myChannelClaimIds.forEach((id) => {
if (byId[id]) {
// I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544
claims.push(byId[id]);