skip to Main Content

Working through this coding exercise and having trouble understanding state changes with Redux…the "RecountVotes" case should activate and re-render the Header component (displaying total votes) every time the RecountVotes function is called but it lags behind one step, displaying the previous collections votes as opposed to the currents…

import { PostsError, PostsLoaded, RecountVotes } from '../actions/posts';

const InitialState = {
  error: null,
  pages: 0,
  posts: [],
  votes: 0,
};

export default function posts(state = InitialState, action) {
  switch (action.type) {
    case PostsError: {
      return {
        ...state,
        error: action.error,
      };
    }

    case PostsLoaded: {
      return {
        ...state,
        error: null,
        pages: action.pages,
        posts: action.posts,
      };
    }

    case RecountVotes: {
      let votes = state.posts.reduce((prev, post) => {
        return prev + post.votes;
      }, 0);

      return {...state, votes}
    };

    default:
      return state;
  }
}

i’ve tried turning the header into a "PureComponent" but that didn’t seem to do much, and it’s driving me crazy!

2

Answers


  1. Redux is not async, hence when you dispatch an action to update the state, the state change does not happen immediately. That’s why when you are trying to access the updated state right after dispatching the action you are getting the old state.

    you can use redux-thunk to solve this, can refer to their official documentation. I can provide you with a samplecode(u can customize according to you)

    export const recountVotes = () => (dispatch, getState) => {
      const { posts } = getState();
      let votes = posts.reduce((prev, post) => prev + post.votes, 0);
      dispatch({ type: 'RecountVotes', votes });
    };
    

    in your Reduce add below

    case RecountVotes: {
      return {...state, votes: action.votes};
    };
    

    i hope this would work properly. Also kindly try to give more context of where you are using these by editing this post so i can help you more efficiently

    Login or Signup to reply.
  2. Solutions

    1. State Update Timing or Lag:
      Use Redux DevTools to inspect the state changes. Verify that the state is updated immediately after the RecountVotes action is dispatched. You can also add a console.log inside the reducer to see the votes calculation:

      case RecountVotes: {
        let votes = state.posts.reduce((prev, post) => prev + post.votes, 0);
        console.log('Calculated votes:', votes);  // Log the new votes count
        return { ...state, votes };
      }
      
    2. State Reference and Immutable Updates:
      • Solution: Ensure that your state changes result in new references so Redux can detect the change:

       case RecountVotes: {
    let votes = state.posts.reduce((prev, post) => prev + post.votes, 0);
    // Update only if the votes have changed
    if (votes !== state.votes) {
      return { ...state, votes };
    }
    return state;  // Return the existing state if there's no change
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search