From 81d77da17ed78a746a64d28a53ea03cdbf74c000 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Tue, 9 Nov 2021 22:46:23 +0800 Subject: [PATCH] Fix states not updated in an immutable way. It's technically incorrect and was causing the GUI to not update sometimes because the reference did not change, despite the array contents did. The GUI just happens to update most of the time due to other state changes. --- ui/redux/reducers/comments.js | 48 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/ui/redux/reducers/comments.js b/ui/redux/reducers/comments.js index ca3869f08..a050ecd3d 100644 --- a/ui/redux/reducers/comments.js +++ b/ui/redux/reducers/comments.js @@ -50,14 +50,38 @@ const defaultState: CommentsState = { fetchingBlockedWords: false, }; -function pushToArrayInObject(obj, key, valueToPush) { +// **************************************************************************** +// Immutable helpers +// **************************************************************************** + +function immPushToArrayInObject(obj, key, valueToPush) { if (!obj[key]) { obj[key] = [valueToPush]; } else if (!obj[key].includes(valueToPush)) { - obj[key].push(valueToPush); + // Filter duplicates + obj[key] = obj[key].concat(valueToPush); } } +function immConcatToArrayInObject(obj, key, arrayToMerge) { + if (obj[key]) { + obj[key] = obj[key].concat(arrayToMerge); + } else { + obj[key] = arrayToMerge; + } +} + +function immPrefixArrayInObject(obj, key, valueToInsert) { + if (obj[key]) { + obj[key] = [valueToInsert, ...obj[key]]; + } else { + obj[key] = [valueToInsert]; + } +} + +// **************************************************************************** +// **************************************************************************** + export default handleActions( { [ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({ @@ -298,9 +322,9 @@ export default handleActions( const comment = comments[i]; commonUpdateAction(comment, commentById, commentIds, i); if (comment.is_pinned) { - pushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id); + immPushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id); } else { - pushToArrayInObject(topLevelCommentsById, claimId, comment.comment_id); + immPushToArrayInObject(topLevelCommentsById, claimId, comment.comment_id); } } } @@ -309,11 +333,11 @@ export default handleActions( for (let i = 0; i < comments.length; ++i) { const comment = comments[i]; commonUpdateAction(comment, commentById, commentIds, i); - pushToArrayInObject(repliesByParentId, parentId, comment.comment_id); + immPushToArrayInObject(repliesByParentId, parentId, comment.comment_id); } } - byId[claimId] ? byId[claimId].push(...commentIds) : (byId[claimId] = commentIds); + immConcatToArrayInObject(byId, claimId, commentIds); commentsByUri[uri] = claimId; } } @@ -353,16 +377,16 @@ export default handleActions( const updateStore = (comment, commentById, byId, repliesByParentId, topLevelCommentsById) => { commentById[comment.comment_id] = comment; - byId[claimId] ? byId[claimId].unshift(comment.comment_id) : (byId[claimId] = [comment.comment_id]); + immPrefixArrayInObject(byId, claimId, comment.comment_id); const parentId = comment.parent_id; if (comment.parent_id) { - pushToArrayInObject(repliesByParentId, parentId, comment.comment_id); + immPushToArrayInObject(repliesByParentId, parentId, comment.comment_id); } else { if (comment.is_pinned) { - pushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id); + immPushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id); } else { - pushToArrayInObject(topLevelCommentsById, claimId, comment.comment_id); + immPushToArrayInObject(topLevelCommentsById, claimId, comment.comment_id); } } }; @@ -372,7 +396,7 @@ export default handleActions( if (ancestors) { ancestors.forEach((ancestor) => { updateStore(ancestor, commentById, byId, repliesByParentId, topLevelCommentsById); - pushToArrayInObject(linkedCommentAncestors, comment.comment_id, ancestor.comment_id); + immPushToArrayInObject(linkedCommentAncestors, comment.comment_id, ancestor.comment_id); }); } @@ -553,6 +577,8 @@ export default handleActions( const claimId = comment.claim_id; for (let i = 0; i < byId[claimId].length; i++) { if (byId[claimId][i] === comment_id) { + // immutable update + byId[claimId] = Array.from(byId[claimId]); byId[claimId].splice(i, 1); break; }