Redux: It is not documented that return value of store.dispatch() may be changed by middleware

Created on 19 Sep 2015  Â·  8Comments  Â·  Source: reduxjs/redux

In the documentation it says that store.dispatch returns (Object†): The dispatched action.

However, in the middleware examples there is the following example that seems to invalidate that assertion:

/**
 * Schedules actions with { meta: { delay: N } } to be delayed by N milliseconds.
 * Makes `dispatch` return a function to cancel the timeout in this case.
 */
const timeoutScheduler = store => next => action => {
  if (!action.meta || !action.meta.delay) {
    return next(action);
  }

  let timeoutId = setTimeout(
    () => next(action),
    action.meta.delay
  );

  return function cancel() {
    clearTimeout(timeoutId);
  };
};

Where the function cancel will be returned by the dispatch instead of the dispatched action.

This is a bit confusing. Is the documentation wrong? Why would you even want the dispatched action to be returned? Am I missing something?

docs

Most helpful comment

We need to document that middleware may choose to return something else from dispatch.

Without middleware, returning action can be handy, for example, to learn the ID of inserted item. With the middleware, the return value can be anything (depending on the middleware)—for example, an asynchronous middleware may choose to return a Promise you can await.

All 8 comments

We need to document that middleware may choose to return something else from dispatch.

Without middleware, returning action can be handy, for example, to learn the ID of inserted item. With the middleware, the return value can be anything (depending on the middleware)—for example, an asynchronous middleware may choose to return a Promise you can await.

Middleware can potentially redefine the return of dispatch. It's especially tricky when dealing with async stuff. However, it should be noted that middleware is a userland configuration, so it's not imposed by the library and is your own decision to include any middleware that affects dispatch's return.

That being said, maybe there should be an extra blurb in the middleware docs to indicate this fact?

I think applyMiddleware() doc makes it pretty clear but I'd say it's worth linking to it from dispatch() doc.

I would suggest that the documentation needs to be changed for dispatch. The way it is written now is not quite true.

Maybe something like:

(Object†): Return value of middleware chain or the dispatched action.

together with a link to middleware would be appropriate?

Also, I think timdorr's explanation is excellent and should maybe be added as a comment in the docs.

The thing is that Store you get by calling createStore() has no idea about middleware. Middleware wraps the store—it's not part of the store's contract per se.

@gaearon: Hm, yes. From an implementation perspective you are entirely right. However, from a usage perspective the difference is not as intuitive.

Maybe we could at least add a note or comment about it and as you said link to the middleware section.

Working on a middleware, it's become a little unclear as the best approach for what return value is most suitable. So I agree the docs could do with being a bit more "in your face" about this flexibility in the implementation.

I've made a PR to make the notes more appropriate in the API https://github.com/rackt/redux/pull/1103

I think this is mostly fixed by #1103, further contributions are welcome.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ilearnio picture ilearnio  Â·  3Comments

benoneal picture benoneal  Â·  3Comments

cloudfroster picture cloudfroster  Â·  3Comments

CellOcean picture CellOcean  Â·  3Comments

parallelthought picture parallelthought  Â·  3Comments