14

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!

Andrew
  • 153
  • 1
  • 1
  • 6
  • I've done something very similar a few days ago, please look [this file at line 74](https://github.com/reenan/door-lock/blob/master/src/pages/Store/components/DoorsList/components/DoorContainer.js#L74) that function is defined at line 20 and it resolves after getting an async action dispatch result. The action is [defined here](https://github.com/reenan/door-lock/blob/master/src/actions/index.js#L94) Hope it helps you! – Renan Souza Jun 20 '19 at 22:51
  • I believe if you return your promise you can chain: `return Promise.resolve(arg1 + arg2)` – Dan D Jun 21 '19 at 01:14

1 Answers1

18

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
});
Fyodor Yemelyanenko
  • 11,264
  • 1
  • 30
  • 38