Search code examples
reactjsreduxreact-reduxaxiosput

Update State in Redux after successful PUT method (axios)


I would like to update Redux State on the basis of one action, as follows:

export const editAction = (itemType, itemContent, id) => (dispatch) => {
  return axios.put(`${url}/${itemType}/${id}`, {
    itemType,
    ...itemContent,
  })
    .then(({ data }) => {
      console.log(data);
      dispatch({
        type: EDIT_SUCCESS,
        itemType,
        data,
        id,
      });
    })
};

I omitted catch block to shorten source code.

What return should I use to update Redux State in reducer after EDIT_SUCCESS action type?

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_SUCCESS:
      return {
        ...state,
        [action.itemType]: [...action.data],
      };
    case ADD_SUCCESS:
      return {
        ...state,
        [action.itemType]: [...state[action.itemType], action.data],
      };
    case EDIT_SUCCESS:
      return {
        ...state,
        // ???,
      };
    case DELETE_SUCCESS:
      return {
        ...state,
        [action.itemType]: [...state[action.itemType].filter(item => item._id !== action.id)],
      };
  }
};

It is quite clear to me how to implement FETCH, ADD and DELETE because I done it (as you can see) but I have no idea how to implement return for EDIT_SUCCESS.

But importantly, after run editAction() (submit button in Formik), editing object is updated (by axios) in the database correctly but State in Redux DevTools as well as view in a browser remains the same. Only when I refresh page, I see the difference.


Solution

  • If you have edited an element, you should look for it and update it.

    Something like:

    const newState = {...state};
    
    const indexOfElementToUpdate = newState[action.itemType].findIndex(item => item._id === action.id);
    
    newState[action.itemType][indexOfElementToUpdate] = action.data;
    
    return newState;