salsita / prism

React / Redux action composition made simple http://salsita.github.io/prism/
496 stars 24 forks source link

Custom action matchers in Saga #16

Closed tomsdev closed 7 years ago

tomsdev commented 8 years ago

Custom action matchers are available in the Updater but not in Saga. As I understand it, at the moment the saga can only take() an action that is local to the component (e.g. wrapped).

One use case would be a global 'REFRESH' action fired in the app that would need each component saga to fetch their data again.

tomkis commented 8 years ago

Custom action matchers are available in the Updater but not in Saga. As I understand it, at the moment the saga can only take() an action that is local to the component (e.g. wrapped).

Actually take or takeEvery can take predicate as an argument therefore this custom logic can be implemented in Sagas as well... the question is though, should this be part of the framework? Since I believe that this should live in userland.

One use case would be a global 'REFRESH' action fired in the app that would need each component saga to fetch their data again.

I don't think this would be possible even with Custom matcher, maybe it wouldn't even make sense to implement it this way. I am in favour of explicit rather than implicit action wrapping in Sagas.

tomsdev commented 8 years ago

I'm not sure what you mean exactly by "explicit rather than implicit action wrapping in Sagas". In Elm, the side effects are declared in the Updater so the way to take() actions that involve side effects is exactly the same as actions that just change the state. Even if in redux-elm the side effects are now declared outside of the Updater (e.g. in local sagas), I'd still expect consistency (and as much power) in the way I can take() actions and in the way they are wrapped or unwrapped.That's why I'm proposing to have the same custom action matchers this library provide for the Updater.

tomkis commented 8 years ago

Could you provide some code snippet about what you have envisioned?

tomkis commented 8 years ago

Since 3.x will support RxJS Sagas and action matching is totally separated from rest of the architecture in favour of https://github.com/salsita/redux-elm/issues/4 I can imagine we could nicely re-use the matching even in Sagas.

const initialState = {
  incremented: 0,
  decremented: 0
};

const reducer = new MatchingReducerFactory(initialState)
  .case('Incremented', model => ({...model, incremented: model.incremented + 1}))
  .case('Decremented', model => ({...model, decremented: model.decremented + 1}))
  .toReducer();

export default action$ => action$
  .scan(reducer)
  .filter(state => state.incremented >= 3 && state.decremented >= 3)
  .map(() => ({ type: 'ShowPopup' }))
  .take(1);
tomkis commented 7 years ago

Closing, solved by Saga & matchers decoupling in v3.