matystl / redux-effect-reducers

Library that enable returning of effects in reducers for redux library
MIT License
15 stars 2 forks source link

architecture questions #2

Open gregwebs opened 8 years ago

gregwebs commented 8 years ago

1) why is there a separate performSideEffects middleware? Why not just setTimeout the effects? 2) what is the purpose of the subscribe/notify functionality?

gregwebs commented 8 years ago

I created an entirely different implementation of the same concept: https://github.com/gregwebs/redux-side-effect/

I think it deals with the listed disadvantages of this approach.

matystl commented 8 years ago
  1. actually performSideEffects is not middleware its closer to store-enhancer. It's not that either because it need to wrap applyMiddleware which is itself store-enhancer.
  2. normal cycle in dispach work like this: call action creator -> go trough middlewares -> call reducers -> notify listeners -> rerender without messing with middlewares it's nice mental mode atomically update state and render happen after that

let's make artifical example with thunk middleware:

 actionCreator() {
    return (dispatch) => {
      dispach(action1);
      dispach(action2);
    }
  }
store.dispach(actionCreator()) 

How many times would normal person expect that listeners will be called? Two sync dispatches one after another so i would like to keep sane model with both dispatch happen and then listener will be called. That is not true actually after first dispatch listeners are called and after second also so they can see state in some transitional state which i don't like.

If you want to modify this behaviour you need to modify how listening(function subscribe) works on store. And for that purpose you must be store enhancer not middleware.

Why is effects not run on another event cycle with set timeout?

I choose second approach to run then in same "event" to be be able dispatch multiple things with atomic properties(you notify listener once).

Example: Imagine you have some ajax caching middleware.

  reducer() {
     case LOAD_SOMETHING:
        //setStateToLoading
        //somehow return or signal that you want to make ajax request
     case AFTER_LOAD_SOMEHTING
        //save data to state unset loading
  }

if yours effects run in sync with actions that mean ajax caching middleware will get that you want to make request see that it have it in cache and imediatly dispach data. Than reducer will be called again and only after than you notify listeners. So anybody who is listening on store will notice that you just load data with no intermediate loading state.