Home > OS >  React-Redux only lastet changed state is shown correctly
React-Redux only lastet changed state is shown correctly

Time:11-03

I need some states from different component But atm only the latest state that changed is shown when i console.log them is shown correctly 3 out the 4 are undefined.

My Action and Reduxer

export const paypal_error =
  (time, timevalidation, acceptBox, sliderDeliveryValue) => (dispatch) => {
    dispatch({
      type: 'PAYPAL_ERROR',
      payload: {
        time,
        timevalidation,
        acceptBox,
        sliderDeliveryValue,
      },
    });
  };


export const paypalReducer = (state = {}, action) => {
  switch (action.type) {
    case 'PAYPAL_ERROR':
      return {
        ...state,
        time: action.payload.time,
        timevalidation: action.payload.timevalidation,
        acceptBox: action.payload.acceptBox,
        sliderDeliveryValue: action.payload.sliderDeliveryValue,
      };
    default:
      return state;
  }
};

My dispatchs, each in a different component

dispatch(paypal_error({ time: date }))
dispatch(paypal_error({ sliderDeliveryValue: event.target.value }));
dispatch(paypal_error({ timeValidation: false }));
dispatch(paypal_error({ acceptBox: !acceptBox }));

CodePudding user response:

You are sending partial state updates but assuming full updates in the reducer function. You'll need some logic to handle partial updates so you aren't overwriting existing state that is undefined in the action payload. You can simply provide a fallback value of the current existing state value properties for each that you might be updating.

Example:

export const paypalReducer = (state = {}, action) => {
  switch (action.type) {
    case 'PAYPAL_ERROR':
      return {
        ...state,
        time: action.payload.time ?? state.time,
        timevalidation: action.payload.timevalidation ?? state.timevalidation,
        acceptBox: action.payload.acceptBox ?? state.acceptbox,
        sliderDeliveryValue:
          action.payload.sliderDeliveryValue ?? state.sliderDeliveryValue,
      };

    default:
      return state;
  }
};

Additionally, the paypal_error action creator takes up to 4 arguments:

paypal_error = (time, timevalidation, acceptBox, sliderDeliveryValue) => ...

Either pass the four args:

dispatch(paypal_error(date));
dispatch(paypal_error(undefined, undefined, undefined, event.target.value));
dispatch(paypal_error(undefined, false));
dispatch(paypal_error(undefined, undefined, !acceptBox));

Or update the action creator to take a single object argument:

paypal_error = ({
  time,
  timevalidation,
  acceptBox,
  sliderDeliveryValue
}) => ...

Since the paypal_error action creator also doesn't appear to be an asynchronous action it doesn't need to return a function with a call to dispatch, it can simply return the action object with computed payload property.

export const paypal_error = ({
  acceptBox,
  sliderDeliveryValue
  time,
  timevalidation,
}) => ({
  type: 'PAYPAL_ERROR',
  payload: {
    acceptBox,
    sliderDeliveryValue
    time,
    timevalidation,
  },
});

CodePudding user response:

You have to spread the state variable

return {
    ...state,
    time: action.payload.time,
    timevalidation: action.payload.timevalidation,
    acceptBox: action.payload.acceptBox,
    sliderDeliveryValue: action.payload.sliderDeliveryValue,
};

Edit 1: As gunwin said, initial state have to be {}

Edit 2:

Your paypal_error function should not take dispatch as an argument if you don't use it

export const paypal_error =
  (time, timevalidation, acceptBox, sliderDeliveryValue) => ({
    type: 'PAYPAL_ERROR',
    payload: {
      time,
      timevalidation,
      acceptBox,
      sliderDeliveryValue
    }
  });
  • Related