Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a promise from an action using thunk and useDispatch (react-redux hooks)?

I just started exploring react-redux hooks and I was curious how to return a promise if I am using thunk and useDispatch(). Essentially I want to achieve the following:

const dispatch = useDispatch();

dispatch(myAction(...args)).then((result) => {
    ...do something with result
});

When my action looks like this:

const myAction = (arg1, arg2) => {
    return (dispatch, getState) => {
        Promise.resolve(arg1 + arg2);
    }
}

I've simplified my problem a lot, but that is essentially what I'm dealing with. When I try to dispatch the above action, I get the error dispatch(...).then is not a function.

I know redux hooks are pretty new, but I was curious if anybody had gotten this to work or would know a solution. I feel like it should be relatively easy to make this work, but I am at a loss. If you need any more information, let me know. Thanks in advance for any help!

like image 267
Andrew Avatar asked Jun 20 '19 21:06

Andrew


People also ask

What does useDispatch return?

useDispatch() ​ This hook returns a reference to the dispatch function from the Redux store. You may use it to dispatch actions as needed.

Can Redux action return value?

Redux actions do not return anything. They just trigger changes of the global state which you can then listen to. If you need to e.g. fetch data (to update the state with) inside an action you need some kind of async action which e.g. redux-thunk provides.

Can we dispatch action from thunk?

Thunks have access to the dispatch method. This can be used to dispatch actions, or even other thunks.

What should a thunk return?

Thunk allows us to dispatch actions manually, which gives us the power to incorporate some logic or run some asynchronous code before dispatching an action. The function returned from action is called a thunk function which is called with two arguments : 1.


1 Answers

As dispatch returns either of two:

  1. For sync action (like dispatch ({type: 'ACTION'}) it will return action object ({type: 'ACTION'} in my example)

  2. For thunk actions (action creators which return functions) it returns the same result returned from action creator.

So for your case just add return statement for your action creator

const myAction = (arg1, arg2) => {
    return (dispatch, getState) => {
        return Promise.resolve(arg1 + arg2);
    }
}

You can make myAction more realistic like so

const myAction = (arg1, arg2) => {
    return (dispatch, getState) => {
        return fetch(/* some request */).then(response => dispatch ({type: 'RESPONSE_RECEIVED', payload: response}));
    }
}

In this case also resolved promise will be returned. Contnents of promise will be object {type: 'RESPONSE_RECEIVED', payload: response}.

Or you can set arbitrary contents for returned promise like so

const myAction = (arg1, arg2) => {
    return (dispatch, getState) => {
        return fetch(/* some request */).then(response => { 
            dispatch ({type: 'RESPONSE_RECEIVED', payload: response})
            return response;
        }
    }
}

In this example resolved promise will be returned but which contains response inside.

In all cases you can chain like you want

dispatch(myAction(...args)).then((result) => {
    ...do something with result
});
like image 116
Fyodor Avatar answered Oct 13 '22 00:10

Fyodor