After trying the various popular approaches (action creators, thunks, sagas, epics, effects, custom middleware), I still felt that maybe there was room for improvement so I documented my journey in this blog article, Where do I put my business logic in a React/Redux application?
Much like the discussions here, I tried to contrast and compare the various approaches. Eventually it led me to introducing a new library redux-logic which takes inspiration from epics, sagas, custom middleware.
It allows you to intercept actions to validate, verify, authorize, as well as providing a way to perform async IO.
Some common functionality can simply be declared like debouncing, throttling, cancellation, and only using the response from the latest request (takeLatest). redux-logic wraps your code providing this functionality for you.
That frees you to implement your core business logic however you like. You don't have to use observables or generators unless you want to. Use functions and callbacks, promises, async functions (async/await), etc.
The code for doing a simple 5s notification would be something like:
const notificationHide = createLogic({
// the action type that will trigger this logic
type: 'NOTIFICATION_DISPLAY',
// your business logic can be applied in several
// execution hooks: validate, transform, process
// We are defining our code in the process hook below
// so it runs after the action hit reducers, hide 5s later
process({ getState, action }, dispatch) {
setTimeout(() => {
dispatch({ type: 'NOTIFICATION_CLEAR' });
}, 5000);
}
});
I have a more advanced notification example in my repo that works similar to what Sebastian Lorber described where you could limit the display to N items and rotate through any that queued up. redux-logic notification example
I have a variety of redux-logic jsfiddle live examples as well as full examples. I'm continuing to work on docs and examples.
I'd love to hear your feedback.