Reducer
A redux-fluent reducer is a simple function combinator, you can use it to build up composite behaviour by gluing small and dedicated functions together.
import { createReducer, ofType } from 'redux-fluent';
export const greetingsReducer = createReducer('greetings')
.actions(
ofType('Roger Waters', 'David Gilmour', 'Nick Mason', /* ... */).map(greetThePinkFloyd),
ofType('B.B. King').map(greetTheBluesBoy),
greetEveryoneElse,
)
.default(() => 'Hello World');
Matching Actions
Having to manually orchestrate the "which action to respond to" impacts negatively on readability and expressiveness of your program. redux-fluent abstracts orchestration into a clean and functional API that lets you focus on your business logic. No more switch-cases!
import { ofType } from 'redux-fluent';
- Yup! It really works pretty much like redux-observable#ofType
Handling Actions
The Single Responsibility Principle says that "a thing should only have one responsibility".
This is the area where a standard redux reducer fails. It is really impossible for a reducer to do only one thing.
We decided to leave to the reducer the only job of composing behaviour and use simple functions (action handlers) to define the transition logic (how to bring the state from A
to B
).
export const increment = (state) => state + 1;
The Counter Example
If from one side actions are meant to describe "what happened", on the other side reducers are responsible for defining the state shape and its transition logic.
// counter.actions.js
import { createAction } from 'redux-fluent';
export const increment = createAction('INCREMENT_COUNTER');
export const decrement = createAction('DECREMENT_COUNTER');
export const reset = createAction('RESET_COUNTER');
// counter.handlers.js
export const increment = (state) => state + 1;
export const decrement = (state) => state - 1;
export const reset = () => 0;
// counter.reducers.js
import { ofType, createReducer } from 'redux-fluent';
import * as actions from './counter.actions'
import * as handlers from './counter.handlers'
export const counterReducer = createReducer('todos')
.actions(
ofType(actions.increment).map(handlers.increment),
ofType(actions.decrement).map(handlers.decrement),
ofType(actions.reset).map(handlers.reset),
)
.default(() => 0);
import { createStore, combineReducers } from 'redux';
import { counterReducer } from './counter.reducers';
export const store = createStore(
combineReducers({ counter: counterReducer }),
);