Skip to content Skip to sidebar Skip to footer

State Is Returning New State Without Touching The State React/redux

Before I start posting the code I will explain what I want to happen and what is happening. I have been working with this all day and finally got something to work. The problem is

Solution 1:

I think you're actually directly mutating the state, and somehow getting away with it in the sense that the component is still updating.

Let's follow the trail of logic:

  1. In deleteComment(), you reference this.props.post. That object is presumably extracted from the store via mapStateToProps, so it's the object reference in the store.
  2. post gets passed to this.props.deleteComments(post)
  3. deleteComments() dispatches ({type : DELETE_COMMENTS, post})
  4. In the reducer, you have let newPost = action.post; newPost.comments = newCommentArray. But, at that point, newPost still points to the exact same object that's already in the store state. So, you've directly mutated it.

Normally, this kind of mutation would result in your component not re-rendering, so I can only assume that some other value extracted in mapState is also getting updated properly, and thus causing a re-render.

As discussed in the Structuring Reducers - Immutable Update Patterns page in the Redux docs, let someVariable = anotherVariable doesn't create a new object reference - it merely creates a second variable that points to the same object reference. Proper immutable updates require copies of every level of nesting that you're working with, not just the one level. In your case, you're creating a new array via _.reject(), but you're not creating a copy of the post object.

So, in the end, your reducer logic is incorrect, and your application is sorta kinda working by accident :)

update

Responding to your question about a proper update: you need to create a copy of the post object and update it with the new comments array, and you need to copy the state object and update it with the new post object. Based off what the rest of your code does, my guess is this should work:

case DELETE_COMMENTS:
     const newCommentArray = _.reject(action.post.comments, {'_id': action.payload});

     const newState = {
         ...state,
         [action.post.id] : {
             ...action.post,
             comments : newCommentArray
         }
     };

     return newState;

Post a Comment for "State Is Returning New State Without Touching The State React/redux"