Why do we need middleware for async flow in Redux?

前端 未结 11 2244
忘了有多久
忘了有多久 2020-11-22 04:17

According to the docs, \"Without middleware, Redux store only supports synchronous data flow\". I don\'t understand why this is the case. Why can\'t the container component

11条回答
  •  悲&欢浪女
    2020-11-22 04:59

    The short answer: seems like a totally reasonable approach to the asynchrony problem to me. With a couple caveats.

    I had a very similar line of thought when working on a new project we just started at my job. I was a big fan of vanilla Redux's elegant system for updating the store and rerendering components in a way that stays out of the guts of a React component tree. It seemed weird to me to hook into that elegant dispatch mechanism to handle asynchrony.

    I ended up going with a really similar approach to what you have there in a library I factored out of our project, which we called react-redux-controller.

    I ended up not going with the exact approach you have above for a couple reasons:

    1. The way you have it written, those dispatching functions don't have access to the store. You can somewhat get around that by having your UI components pass in all of the info the dispatching function needs. But I'd argue that this couples those UI components to the dispatching logic unnecessarily. And more problematically, there's no obvious way for the dispatching function to access updated state in async continuations.
    2. The dispatching functions have access to dispatch itself via lexical scope. This limits the options for refactoring once that connect statement gets out of hand -- and it's looking pretty unwieldy with just that one update method. So you need some system for letting you compose those dispatcher functions if you break them up into separate modules.

    Take together, you have to rig up some system to allow dispatch and the store to be injected into your dispatching functions, along with the parameters of the event. I know of three reasonable approaches to this dependency injection:

    • redux-thunk does this in a functional way, by passing them into your thunks (making them not exactly thunks at all, by dome definitions). I haven't worked with the other dispatch middleware approaches, but I assume they're basically the same.
    • react-redux-controller does this with a coroutine. As a bonus, it also gives you access to the "selectors", which are the functions you may have passed in as the first argument to connect, rather than having to work directly with the raw, normalized store.
    • You could also do it the object-oriented way by injecting them into the this context, through a variety of possible mechanisms.

    Update

    It occurs to me that part of this conundrum is a limitation of react-redux. The first argument to connect gets a state snapshot, but not dispatch. The second argument gets dispatch but not the state. Neither argument gets a thunk that closes over the current state, for being able to see updated state at the time of a continuation/callback.

提交回复
热议问题