Search code examples
reduxredux-thunkredux-promiseredux-promise-middleware

What is the point of Redux Promise and Redux Promise Middleware?


I've searched high and low but can't find a clear answer.

I've managed to wrap my head around the mechanics of Redux, but when I've come to the point of API calls and async action creators, I'm stuck with middleware in context of Promises.

Can you help me get the mess right?

Cotradictory pieces of the puzzle giving me headache:

  1. One of YT tutorials says that natively Redux dispatch method does not support promises returned from action creators--hence the need for Redux Promise library (I know the project is probably dead now and the continuation is Redux Promise Middleware).

  2. Dan says in "What is the difference between redux-thunk and redux-promise?" I can use promises even without middleware--just manage them in the action creator.

  3. In other answers I found examples of using thunks where the action creator returned a... promise (later is was processed in the caller /dispatch(myActionCreator(params).then(...)/ So a promise can be returned by a thunk WITHOUT any redux-promise lib..?

  4. In "What is the difference between redux-thunk and redux-promise?", the accepted answer states Redux Thunk returns functions, whereas Redux Promise returns promises.. what the heck?

To wrap it up: what's the point of using Redux Promise or Redux Promise Middleware? Why does Redux alone not natively support promises?

Update:

I've just realized that in point 3 above I overlooked then() being attached to dispatch and not included in dispatch() args.


Solution

  • The linked answers are correct, but I'll try to explain further.

    A basic Redux store will only accept dispatching plain object actions:

    store.dispatch({type : "ADD_TODO", text : "Buy milk"});
    

    If you try to pass anything other than a plain object action, the store will throw an error:

    store.dispatch(() => {});
    // Error: "Actions must be plain objects. Use custom middleware for async actions."
    

    Middleware form a pipeline around store.dispatch(), and each middleware can do anything it wants with whatever value was passed to dispatch: modify it, log it, delay it, or dispatch something else instead it. That means that a middleware can "teach" dispatch() how to accept something that's not a plain action object, by intercepting the value and doing something else instead.

    So, redux-thunk "teaches" dispatch how to accept functions, by intercepting the function and calling it instead of passing it on to the reducers. redux-promise "teaches" dispatch how to accept promises, by intercepting the promise and dispatching actions when the promise resolves or rejects.

    Normally, dispatch returns whatever action object was passed in. Because middleware wrap around dispatch, they can also change what value is being returned. redux-thunk will run the thunk function, and return whatever that thunk function returns. That lets you do useful things like return a promise from a thunk, and chain behavior from there:

    dispatch(someThunkReturningAPromise())
        .then(() => {
            // Do more stuff here
        });
    

    For more info on the topic, see the Redux FAQ entry on dealing with side effects, and the articles in the Redux Side Effects section of my React/Redux links list.