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
}
});