Some Stripes modules including stripes-core and ui-eholdings have written by using redux, react-redux and redux-observable for state management. stripes-core is kind a wrapper for the whole other UI modules and its reducer and epic is kind of root ones. Every UI application is able to register its own reducers and epics in root. This is done by using withRoot HOC from '@folio/stripes-core/src/components/Root/RootContext' which provides addReducer and addEpic methods. The main idea is to call this methods by passing all combined reducers and epics of the particular module and not one by one.
...
STATE_MANAGEMENT.REDUCER and STATE_MANAGEMENT.EPIC are constants which usually equal to the name of the particular project (e.g. data-import).
Redux
Redux is a global state management object for your react app. Its basic idea comes from the flux architecture. redux is needed because react app gets bigger. It’s hard to manage state. If two child component share the same state from parents. The child must pass the state back to parent and then to the other child component. To solve this problem, we need a global store.
Not every state should be placed inside redux. UI state of, for example whether the dropdown is open, is okay to store in component state. Additionally redux can be replaced with usage of react context feature.
...
redux-observable is a middleware in Redux. Middleware provides a third-party extension point between dispatching an action, and the moment it reaches the reducer. People use Redux middleware for logging, crash reporting, talking to an asynchronous API, routing, and more. redux-observable is RxJS 6-based middleware for Redux. Compose and cancel async actions to create side effects and more. Epic is a term in redux-observable which denotes an asynchronous action which are usually called side effects. An Epic is the core primitive of redux-observable. It is a function which takes a stream of actions and returns a stream of actions. Actions in, actions out.
function (action$: Observable<Action>, state$: StateObservable<State>): Observable<Action>;
redux-observable is based on RxJs which is Reactive Extensions Library for JavaScript. RxJs is a set of libraries for composing asynchronous and event-based programs using observable sequences and fluent query operators that many of you already know by Array#extras in JavaScript. Using RxJS, developers represent asynchronous data streams with Observables, query asynchronous data streams using our many operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, RxJS = Observables + Operators + Schedulers.
Example of sample epic:
Code Block |
---|
import { of as of$ } from 'rxjs/observable/of'; import { concat as concat$ } from 'rxjs/observable/concat'; import 'rxjs/add/operator/delay'; import 'rxjs/add/operator/switchMap'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import { SEARCH, searchInProgress, searchSuccess, searchFailed } from '../../actions'; export const searchEpic = action$ => { return action$ .ofType(SEARCH) .switchMap(() => concat$( of$(searchInProgress()), of$([{ a: 1 }, { a: 2 }]) .delay(1000) .map(data => searchSuccess(data)) .catch(e => of$(searchFailed(e))) ) ); }; |
...