Comments: fix memoization of selectors #7227

Closed
infinite-persistence wants to merge 3 commits from ip/memo into master
4 changed files with 34 additions and 24 deletions

View file

@ -19,17 +19,21 @@ import { selectActiveChannelClaim } from 'redux/selectors/app';
import { selectPlayingUri } from 'redux/selectors/content'; import { selectPlayingUri } from 'redux/selectors/content';
import Comment from './view'; import Comment from './view';
const select = (state, props) => { const makeMapStateToProps = (originalState, originalProps) => {
const activeChannelClaim = selectActiveChannelClaim(state); const activeChannelClaim = selectActiveChannelClaim(originalState);
const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id; const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id;
const reactionKey = activeChannelId ? `${props.commentId}:${activeChannelId}` : props.commentId; const reactionKey = activeChannelId ? `${originalProps.commentId}:${activeChannelId}` : originalProps.commentId;
const selectOthersReactionsForComment = makeSelectOthersReactionsForComment(reactionKey);
const select = (state, props) => {
const othersReacts = selectOthersReactionsForComment(state);
return { return {
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
thumbnail: props.authorUri && makeSelectThumbnailForUri(props.authorUri)(state), thumbnail: props.authorUri && makeSelectThumbnailForUri(props.authorUri)(state),
channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state), channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state),
commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true, commentingEnabled: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true,
othersReacts: makeSelectOthersReactionsForComment(reactionKey)(state), othersReacts,
activeChannelClaim, activeChannelClaim,
myChannels: selectMyChannelClaims(state), myChannels: selectMyChannelClaims(state),
playingUri: selectPlayingUri(state), playingUri: selectPlayingUri(state),
@ -38,6 +42,8 @@ const select = (state, props) => {
totalReplyPages: makeSelectTotalReplyPagesForParentId(props.commentId)(state), totalReplyPages: makeSelectTotalReplyPagesForParentId(props.commentId)(state),
}; };
}; };
return select;
};
const perform = (dispatch) => ({ const perform = (dispatch) => ({
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
@ -47,4 +53,4 @@ const perform = (dispatch) => ({
doToast: (options) => dispatch(doToast(options)), doToast: (options) => dispatch(doToast(options)),
}); });
export default connect(select, perform)(Comment); export default connect(makeMapStateToProps, perform)(Comment);

View file

@ -361,7 +361,9 @@ function Comment(props: Props) {
icon={ICONS.REPLY} icon={ICONS.REPLY}
/> />
)} )}
{ENABLE_COMMENT_REACTIONS && <CommentReactions uri={uri} commentId={commentId} />} {ENABLE_COMMENT_REACTIONS && (
<CommentReactions uri={uri} commentId={commentId} othersReacts={othersReacts} />
)}
</div> </div>
)} )}

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Comment from './view'; import CommentReactions from './view';
import { makeSelectClaimIsMine, makeSelectClaimForUri, doResolveUri } from 'lbry-redux'; import { makeSelectClaimIsMine, makeSelectClaimForUri, doResolveUri } from 'lbry-redux';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
import { makeSelectMyReactionsForComment, makeSelectOthersReactionsForComment } from 'redux/selectors/comments'; import { makeSelectMyReactionsForComment, makeSelectOthersReactionsForComment } from 'redux/selectors/comments';
@ -15,7 +15,7 @@ const select = (state, props) => {
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
claimIsMine: makeSelectClaimIsMine(props.uri)(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state),
myReacts: makeSelectMyReactionsForComment(reactionKey)(state), myReacts: makeSelectMyReactionsForComment(reactionKey)(state),
othersReacts: makeSelectOthersReactionsForComment(reactionKey)(state), othersReacts: props.othersReacts || makeSelectOthersReactionsForComment(reactionKey)(state),
activeChannelId, activeChannelId,
}; };
}; };
@ -26,4 +26,4 @@ const perform = (dispatch) => ({
doToast: (params) => dispatch(doToast(params)), doToast: (params) => dispatch(doToast(params)),
}); });
export default connect(select, perform)(Comment); export default connect(select, perform)(CommentReactions);

View file

@ -5,6 +5,8 @@ import { selectShowMatureContent } from 'redux/selectors/settings';
import { selectBlacklistedOutpointMap, selectFilteredOutpointMap } from 'lbryinc'; import { selectBlacklistedOutpointMap, selectFilteredOutpointMap } from 'lbryinc';
import { selectClaimsById, isClaimNsfw, selectMyActiveClaims } from 'lbry-redux'; import { selectClaimsById, isClaimNsfw, selectMyActiveClaims } from 'lbry-redux';
type State = { comments: CommentsState };
const selectState = (state) => state.comments || {}; const selectState = (state) => state.comments || {};
export const selectCommentsById = createSelector(selectState, (state) => state.commentById || {}); export const selectCommentsById = createSelector(selectState, (state) => state.commentById || {});
@ -13,7 +15,7 @@ export const selectIsFetchingCommentsById = createSelector(selectState, (state)
export const selectIsFetchingCommentsByParentId = createSelector(selectState, (state) => state.isLoadingByParentId); export const selectIsFetchingCommentsByParentId = createSelector(selectState, (state) => state.isLoadingByParentId);
export const selectIsPostingComment = createSelector(selectState, (state) => state.isCommenting); export const selectIsPostingComment = createSelector(selectState, (state) => state.isCommenting);
export const selectIsFetchingReacts = createSelector(selectState, (state) => state.isFetchingReacts); export const selectIsFetchingReacts = createSelector(selectState, (state) => state.isFetchingReacts);
export const selectOthersReactsById = createSelector(selectState, (state) => state.othersReactsByCommentId); export const selectOthersReactsById = (state: State) => state.comments.othersReactsByCommentId;
export const selectPinnedCommentsById = createSelector(selectState, (state) => state.pinnedCommentsById); export const selectPinnedCommentsById = createSelector(selectState, (state) => state.pinnedCommentsById);
export const makeSelectPinnedCommentsForUri = (uri: string) => export const makeSelectPinnedCommentsForUri = (uri: string) =>
@ -191,12 +193,12 @@ export const makeSelectMyReactionsForComment = (commentIdChannelId: string) =>
}); });
export const makeSelectOthersReactionsForComment = (commentId: string) => export const makeSelectOthersReactionsForComment = (commentId: string) =>
createSelector(selectState, (state) => { createSelector(selectOthersReactsById, (othersReactsByCommentId) => {
if (!state.othersReactsByCommentId) { if (!othersReactsByCommentId) {
return {}; return {};
} }
return state.othersReactsByCommentId[commentId] || {}; return othersReactsByCommentId[commentId] || {};
}); });
export const selectPendingCommentReacts = createSelector(selectState, (state) => state.pendingCommentReactions); export const selectPendingCommentReacts = createSelector(selectState, (state) => state.pendingCommentReactions);