Search code examples
reactjsreduxreact-reduxredux-saga

Same redux actions dispatched in quick succession


I have an application with like button. User can like multiple posts in quick succession. I send the action to update likecount and add like/user record through a redux action.

export const likePost = (payload) => (dispatch) => {
  dispatch({
    type: "LIKE_POST",
    payload,
  });
};

In the saga on successful update, the control of action comes in both cases but LIKE_POST_SUCCESSFUL is triggered only for the last.

function* requestLikePost(action) {
  const { postId } = action.payload;
  try {
    const response = yield call(callLikePostsApi, postId);
    yield put({
      type: "LIKE_POST_SUCCESSFUL",
      payload: response.data,
    });
  } catch (error) {
    yield put({
      type: "LIKE_POST_FAILED",
      payload: error.response.data,
    });
  }
}

These are recieving action in reducer. The LIKE_POST is triggered two times as expected but not the LIKE_POST_SUCCESSFUL, its triggered only for the last though both reached .

case "LIKE_POST":
      return {
        ...state,
        errors: {},
       
      };
    case "LIKE_POST_SUCCESSFUL":
      updatedPosts = state.posts.map((post) => {
        if (post.postId === action.payload.postId) {
          return action.payload;
        }
        return post;
      });
      updatedLikes = [
        ...state.likes,
        { userName: state.profile.userName, postId: action.payload.postId },
      ];
      console.log("updatedLikes", updatedLikes, action.payload);
      return {
        ...state,
        posts: updatedPosts,
        likes: updatedLikes,
        loading: false,
      };

API call

const callLikePostsApi = (postId) => axios.get(`/post/${postId}/like`);

Solution

  • Are you using takeLatest() effect for your saga function requestLikePost? It will take only latest action call into consideration and aborts all the previous calls if it happens in quick succession.

    Use takeEvery() saga effect instead.