Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement useReducer for Comment State Management (React commenting) #9801

Merged
merged 1 commit into from
Jun 15, 2021

Conversation

noi5e
Copy link
Contributor

@noi5e noi5e commented Jun 15, 2021

Part of a React rewrite of the commenting system, see #9365 for more context.

In this PR, I begin to switch state management from React's useState hook to useReducer instead. useReducer is modeled after other React state management libraries like Redux.

Why the switch? The app state is starting to get very complex, and will only get more complex as features are added. For example, let's take the example of "disable submit comment button after user clicks on it, and before server sends a response". This is a feature which I'm going to start work on soon, and it will require adding more variables into state: waitingForServerResponse, submitButtonIsDisabled, and the like.

Switching over to useReducer will make this codebase easier to understand and debug in the long run.

I've created a new reducers.js file. Everything the app does that changes state will be described in this file. For now, it looks like this:

/* eslint-disable complexity */
import { makeDeepCopy } from "./helpers";

const reducer = (state, action) => {
  switch(action.type) {
    case "CREATE COMMENT":
      return {
        ...state,
        comments: [
          ...state.comments, 
          action.newComment
        ]
      };
    case "UPDATE COMMENT":
      for (let i = 0; i < state.comments.length; i++) {
        // find the comment in state
        if (state.comments[i].commentId === action.newComment.commentId) {
          let newComment = makeDeepCopy(state.comments[i]);
          newComment.htmlCommentText = action.newComment.htmlCommentText; // update comment text
          newComment.rawCommentText = action.newComment.rawCommentText;
          return {
            ...state,
            comments: Object.assign(
              [],
              state.comments,
              { [i]: newComment }
            )
          }; // keep the rest of state.comments, but replace comment at index i with newComment
        }
      }
      break;
    case "DELETE COMMENT":
      for (let i = 0; i < state.comments.length; i++) {
        // find the comment in state by ID
        if (state.comments[i].commentId === action.commentId) {
          return {
            ...state,
            comments: state.comments.filter(comment => action.commentId !== comment.commentId)
          };
        }
      }
      break;
    default:
      throw new Error(); // default should never be called
  }
}

export {
  reducer
}

(This issue is part of the larger Comment Editor Overhaul Project with Outreachy. Refer to Planning Issue #9069 for more context)

@gitpod-io
Copy link

gitpod-io bot commented Jun 15, 2021

/* eslint-disable complexity */
import { makeDeepCopy } from "./helpers";

const reducer = (state, action) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function reducer has a Cognitive Complexity of 11 (exceeds 5 allowed). Consider refactoring.

/* eslint-disable complexity */
import { makeDeepCopy } from "./helpers";

const reducer = (state, action) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function reducer has 39 lines of code (exceeds 25 allowed). Consider refactoring.

@@ -0,0 +1,50 @@
/* eslint-disable complexity */
import { makeDeepCopy } from "./helpers";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing error: 'import' and 'export' may appear only with 'sourceType: module'

@codeclimate
Copy link

codeclimate bot commented Jun 15, 2021

Code Climate has analyzed commit 7e76038 and detected 4 issues on this pull request.

Here's the issue category breakdown:

Category Count
Complexity 3
Style 1

View more on Code Climate.

@codecov
Copy link

codecov bot commented Jun 15, 2021

Codecov Report

❗ No coverage uploaded for pull request base (main@700fdf4). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #9801   +/-   ##
=======================================
  Coverage        ?   82.07%           
=======================================
  Files           ?       98           
  Lines           ?     5940           
  Branches        ?        0           
=======================================
  Hits            ?     4875           
  Misses          ?     1065           
  Partials        ?        0           

@noi5e
Copy link
Contributor Author

noi5e commented Jun 15, 2021

Ready to merge! Tests pass. Asking for an override on the codeclimate issues :)

@jywarren
Copy link
Member

Fantastic work, @noi5e, thank you!

@jywarren jywarren merged commit 596ff0c into publiclab:main Jun 15, 2021
@jywarren jywarren changed the title Implement useReducer for Comment State Management Implement useReducer for Comment State Management (React commenting) Jun 15, 2021
@noi5e noi5e deleted the react-implement-useReducer branch June 17, 2021 06:05
reginaalyssa pushed a commit to reginaalyssa/plots2 that referenced this pull request Oct 16, 2021
billymoroney1 pushed a commit to billymoroney1/plots2 that referenced this pull request Dec 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants