Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux action return type when using dispatch and getState

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>'

like image 971
Alan Schapira Avatar asked Jun 11 '18 09:06

Alan Schapira


People also ask

What happens when you dispatch an action Redux?

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.

What does the dispatch method return?

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.

What happens when you try to dispatch an action within a reducer?

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.

What does an action creator return in Redux?

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.


1 Answers

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;
}
like image 187
Alan Schapira Avatar answered Sep 23 '22 17:09

Alan Schapira