redux-stream
Warning: Very experimental. Do not use in production.
Use RxJS 5 to compose streams of side effects with Redux. redux-stream is a Redux store enhancer that works alongside middleware, so it is possible to gradually introduce redux-stream into an application that makes use of thunk-middleware.
Side effect composing of:
- Ajax
- Inter module actions (eg. selecting a search filter triggers a search)
- Independent modules' state changes
- Independent modules' actions
Dan Abramov opened up an issue on Redux: https://github.com/reactjs/redux/issues/1528
Problem: Side Effects and Composition
... This is the big problem with middleware. When you compose independent apps into a single app, neither of them is “at the top”. This is where the today’s Redux paradigm breaks down—we don’t have a good way of composing side effects of independent “subapplications”.
redux-stream provides a solution to this issue through state streams. When composing your module's side effects, you have access to all state streams, which allows you to react to an independent module's state changes and produce side effects from it.
Composing side effects
Ajax
;; // Side effect producerconst searchResponse = action$ // Grab the query from the payload // Go to the server with the query // Map the server response to the response action // Plain old reducer { }; // Compose module with side effects and reducerproductSearch = productSearch; // Create Redux store - enhanced with Redux Stream (no need to // combine reducers)const store = ; store; store;// >_ Search state: { searching: true, results: [] }// Searching...// >_ Search state: { searching: false, results: [20] }
Inter module side effects
const initialState = searching: false movies: searchPhrase: '' genres: 'Drama' releaseYear: 2016 ; /** * Search side effect producer. * When selecting genres or year of release, we need to trigger a * movie search (only if we haven't unselected all genres) */const searchSideEffect = Observable // Only search if we have genres selected // Search response side effect producerconst searchResponse = action$ // Grab the query from the payload // Go to the server with the query (integrates with promises) // Map the server response to the response action // The reducer { }; // Compose module with side effects and reducermovieSearch = movieSearch; const store = ; store; store;// >_ Movies state: { searching: false, movies: [], searchPhrase: '', genres: ['Drama', 'Action'], ... }// >_ Movies state: { searching: true, movies: [], searchPhrase: '', genres: ['Drama', 'Action'], ... }// Searching...// >_ Movies state: { searching: false, movies: [20], searchPhrase: '', genres: ['Drama', 'Action'], ... }
Composing side effects of independent modules
{ } // Side effect producerconst computedResult = // Listen to state changes - skip the initial state // Grab the state we are interested in // Only react when it changes // Map it as the payload to a new action { } // Compose module with side effects and reducersideEffectModule = sideEffectModule; const store = ; store; store;// >_ Subject state: { computed: 100 }// >_ Side effect state: { results: [] }// ...// >_ Subject state: { computed: 100 }// >_ Side effect state: { results: [100] } store;// >_ Subject state: { computed: 1000 }// >_ Side effect state: { results: [100] }// ...// >_ Subject state: { computed: 1000 }// >_ Side effect state: { results: [100, 1000] }