How to Avoid Get/Set Actions in Redux

reactiveredux

The point of redux is to decouple "what happened" from "how the state changes" according to Dan, anyway, but I'm having trouble figuring out how to handle side effects without having getters and setters.

Here's where I am now:

  • User enters email + password and taps "log in"
  • App fires off { type: "USER/LOGIN", payload: { email, password } }
  • Middleware sees "USER/LOGIN" and makes an HTTP request
  • Reducer sees "USER/LOGIN" and updates state to fetching

THIS IS WHERE I GET STUCK

Here's how I'm handing it now, but it feels like I'm doing something wrong:

  • Response comes back
  • If we get a user, dispatch { type: "USER/LOAD", payload: { … } }
  • If we didn't, dispatch { type: "USER/ERROR", payload: { … } }

Is this right?

Best Answer

It's close, but no.

The main problem lies in the way you are initiating the asynchronous action. The handling of the response is completely correct.

Basically, you are firing an action to mean "Do this special other thing", and that is wrong. You should be updating the state to mean "Do this special other thing". Then it can be updated by any action in any situation you need.

  • User enters email + password and taps "log in"
  • App fires off { type: "USER/LOGIN", payload: { email, password } }
  • Reducer sees "USER/LOGIN" and updates state to fetching
  • Middleware sees state was in "unfetched" and is now in "fetching" and makes an HTTP request

As a further generalization, we have employed a continuation- basically, you store an action on the store state, and fire that in addition. This is kind of a Redux way of doing promise.then().