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.
This commit is contained in:
infinite-persistence 2021-11-09 22:46:23 +08:00
parent 7cefb0fadc
commit 81d77da17e
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0

View file

@ -50,14 +50,38 @@ const defaultState: CommentsState = {
fetchingBlockedWords: false, fetchingBlockedWords: false,
}; };
function pushToArrayInObject(obj, key, valueToPush) { // ****************************************************************************
// Immutable helpers
// ****************************************************************************
function immPushToArrayInObject(obj, key, valueToPush) {
if (!obj[key]) { if (!obj[key]) {
obj[key] = [valueToPush]; obj[key] = [valueToPush];
} else if (!obj[key].includes(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( export default handleActions(
{ {
[ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({ [ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({
@ -298,9 +322,9 @@ export default handleActions(
const comment = comments[i]; const comment = comments[i];
commonUpdateAction(comment, commentById, commentIds, i); commonUpdateAction(comment, commentById, commentIds, i);
if (comment.is_pinned) { if (comment.is_pinned) {
pushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id); immPushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id);
} else { } 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) { for (let i = 0; i < comments.length; ++i) {
const comment = comments[i]; const comment = comments[i];
commonUpdateAction(comment, commentById, commentIds, 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; commentsByUri[uri] = claimId;
} }
} }
@ -353,16 +377,16 @@ export default handleActions(
const updateStore = (comment, commentById, byId, repliesByParentId, topLevelCommentsById) => { const updateStore = (comment, commentById, byId, repliesByParentId, topLevelCommentsById) => {
commentById[comment.comment_id] = comment; 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; const parentId = comment.parent_id;
if (comment.parent_id) { if (comment.parent_id) {
pushToArrayInObject(repliesByParentId, parentId, comment.comment_id); immPushToArrayInObject(repliesByParentId, parentId, comment.comment_id);
} else { } else {
if (comment.is_pinned) { if (comment.is_pinned) {
pushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id); immPushToArrayInObject(pinnedCommentsById, claimId, comment.comment_id);
} else { } else {
pushToArrayInObject(topLevelCommentsById, claimId, comment.comment_id); immPushToArrayInObject(topLevelCommentsById, claimId, comment.comment_id);
} }
} }
}; };
@ -372,7 +396,7 @@ export default handleActions(
if (ancestors) { if (ancestors) {
ancestors.forEach((ancestor) => { ancestors.forEach((ancestor) => {
updateStore(ancestor, commentById, byId, repliesByParentId, topLevelCommentsById); 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; const claimId = comment.claim_id;
for (let i = 0; i < byId[claimId].length; i++) { for (let i = 0; i < byId[claimId].length; i++) {
if (byId[claimId][i] === comment_id) { if (byId[claimId][i] === comment_id) {
// immutable update
byId[claimId] = Array.from(byId[claimId]);
byId[claimId].splice(i, 1); byId[claimId].splice(i, 1);
break; break;
} }