Muteshi
Muteshi

Reputation: 1318

React Redux store not updating on delete of an item from state

I am using @reduxjs/toolkit to create delete reducer a as follows:

const slice = createSlice({
  name: "hotels",
  initialState: {
    list: [],
    loading: false,
    lastFetch: null,
  },
  reducers: {
    hotelsRequested: (hotels) => {
      hotels.loading = true;
    },
    hotelsRequestFailed: (hotels) => {
      hotels.loading = false;
    },
    hotelsReceived: (hotels, action) => {
      hotels.list = action.payload;
      hotels.loading = false;
      hotels.lastFetch = Date.now();
    },

    hotelDeleted: (hotels, action) =>
      hotels.list.filter((hotel) => hotel.slug !== action.payload.slug),
  },
});

export const {
  hotelsReceived,
  hotelsRequestFailed,
  hotelsRequested,
  hotelDeleted,
} = slice.actions;
export default slice.reducer;

Delete action is below

export const loadHotels = () => (dispatch, getState) => {
  const { lastFetch } = getState().entities.hotels;
  const diffInMinutes = moment().diff(lastFetch, "minutes");
  if (diffInMinutes < 10) return;
  dispatch(
    hotelApiCallBegan({
      url: hotelUrl,
      onStart: hotelsRequested.type,
      onSuccess: hotelsReceived.type,
      onError: hotelsRequestFailed.type,
    })
  );
};
export const deleteHotel = (slug) =>
  hotelApiCallBegan({
    url: `/hotel/${slug}/delete/`,
    method: "delete",
    onSuccess: hotelDeleted.type,
  });

Here is the middleware

export const hotelsApi = ({ dispatch }) => (next) => async (action) => {
  if (action.type !== actions.hotelApiCallBegan.type) return next(action);

  const { onStart, onSuccess, onError, url, method, data } = action.payload;

  if (onStart) dispatch({ type: onStart });

  next(action);
  try {
    const response = await axiosInstance.request({
      baseURL,
      url,
      method,
      data,
    });

    //General
    dispatch(actions.hotelApiCallSuccess(response.data));
    //Specific
    if (onSuccess) dispatch({ type: onSuccess, payload: response.data });
  } catch (error) {
    //general error
    dispatch(actions.hotelApiCallFailed(error.message));
    //Specific error
    if (onError) dispatch({ type: onError, payload: error.message });
  }
};

When i click on delete button on ui using onClick={() => this.props.onDelete(hotel.slug)} i can see on the networks tab on chrome dev tools that the hotel is deleted. But the state remains unchanged until page refresh. What could be wrong here?

Upvotes: 1

Views: 2875

Answers (1)

Domino987
Domino987

Reputation: 8774

You need to return the hotel list:

return hotels.list.filter((hotel) => hotel.slug !== slug);

or

hotelDeleted: (hotels, action) => hotels.list.filter((hotel) => hotel.slug !== action.payload.slug)

// Update

For using immer (used under the hood by the toolkit), you have to delete it differently. Not by using filter.

 hotelDeleted: (hotels, action) => {
  const { slug } = action.payload;
  const index = hotels.list.findIndex((hotel) => hotel.slug !== slug);
  hotels.list.splice(index, 1);
},

Upvotes: 2

Related Questions