Some Stripes modules including stripes-core and ui-eholdings are written using redux, react-redux and redux-observable for state management. stripes-core is a wrapper for other UI modules and their reducers and epic is a kind of root one. 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 the addReducer and addEpic methods. The main idea is to call these 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. The 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 all state should be placed inside redux. For example whether a dropdown is open is okay to store in component state. Additionally redux can be replaced with usage of react context feature.
Example An example of action type:
Code Block |
---|
export const ADD_RECIPE = 'ADD_RECIPE'; |
Example And example of action:
Code Block |
---|
export const addRecipe = payload => ({ type: types.ADD_RECIPE, payload, }) |
Example An example of reducer:
Code Block |
---|
const initialState = { recipes: [], }; export default function(state = initialState, action){ switch (action.type) { case ADD_RECIPE: return [ ...state, recipes: { ...state.recipes, { name: action.recipe.name, ingredients: action.recipe.ingredients, }, }, ]; default: return state; } } |
...
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))) ) ); }; |
...
A good place to store redux stuff is under src/redux folder. The actions folder stands for react actions, redux for reducers, epics for side effects.
Debugging
The Redux team implemented a handy tool for working with state management. It is redux-devtools chrome extension. It provides a way to see what exact actions with what payload was fired and allows you to see the whole application state and much more. Folio UI application has the needed setup so the only requirement is to install extension.
...