I am struggling to figure out what the return type should be for my action. Everything works whilst I am using any
but am trying to avoid using any
.
export const saveValue = (value: number): any => {
return (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
const someValueFromState = getState().stateValue;
const payload = {...response, someValueFromState}
dispatch({ type: constants.SAVE_VALUE, payload });
});
};
};
I had it working before when the action was not using getState()
and it looked like this, where it returned Dispatch<SaveValue>
:
export const saveValue = (value: number): Dispatch<SaveValue> => {
return (dispatch: Dispatch<SaveValue>): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
dispatch({ type: constants.SAVE_VALUE, response });
});
};
};
But once I added getState, I am not sure what to do anymore. I have tried to put the return value in a variable and can see the object I am creating is const myAttempt: (dispatch: Dispatch<SaveValue>, getState: () => State) => void
but when I tried to use it as follows, it doesn't work:
export const saveValue = (value: number): (dispatch: Dispatch<SaveValue>, getState: () => StoreState) => void => {
return (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
const someValueFromState = getState().stateValue;
const payload = {...response, someValueFromState}
dispatch({ type: constants.SAVE_VALUE, payload });
});
};
};
Doing this, I get an error: A function whose declared type is neither 'void' nor 'any' must return a value.
EDIT:
Just to add, I cannot return Dispatch<SaveValue>
as I was before, otherwise I get this error: Type '(dispatch: Dispatch<SaveValue>, getState: () => State) => void' is not assignable to type 'Dispatch<SaveValue>'
The app code dispatches an action to the Redux store, like dispatch({type: 'counter/incremented'}) The store runs the reducer function again with the previous state and the current action , and saves the return value as the new state.
The handler uses the dispatch function to dispatch an action. React calls the reducer. React passes the current state and the dispatched action to the reducer. The reducer returns the new state.
Dispatching an action within a reducer is an anti-pattern. Your reducer should be without side effects, simply digesting the action payload and returning a new state object. Adding listeners and dispatching actions within the reducer can lead to chained actions and other side effects.
An action creator is a function that literally creates an action object. In Redux, action creators simply return an action object and pass the argument value if necessary.
A friend helped me answer this. This was the right way to do it:
export const saveValue = (value: number): (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
return (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
const someValueFromState = getState().stateValue;
const payload = {...response, someValueFromState}
dispatch({ type: constants.SAVE_VALUE, payload });
});
};
};
The issue I was having was with my mapDispatchToProps
function which was being explicitly typed and causing the error Type '(dispatch: Dispatch<SaveVisit>, getState: () => StoreState) => void' is not assignable to type 'Dispatch<SaveVisit>'
. The function was:
interface MapDispatchToPropsInterface {
saveValue : (value: number) => Dispatch<SaveValue>;
}
const mapDispatchToProps: MapDispatchToPropsInterface = {
saveValue : ActionCreators.saveValue,
};
but the interface needed to be:
interface MapDispatchToPropsInterface {
saveValue : (saveDetails: CheckedVisit) => (dispatch: Dispatch<SaveValue>, getState: () => StoreState) => void;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With