The one thing that has irked me in every reducer based state management system is the reducer itself. It is a daunting task to be a full time state ninja slicing/merging arrays and objects, flipping/toggling countless flags and extracting/assigning values in every decrepit corner of your application state. To add insult to injury, all the above tasks have to be done keeping in mind the idiosyncrasies of our overlord, the state reducer, whose purity must be preserved in all its glory at all times. Kubric's reducer-factory tries to put an end to the tyrannical rule of reducers by reducing them to a mere configuration and freeing the developer from the shackles of dull state operations.
Notwithstanding the tall claims made in the above tirade, Redux with its reducer based state management is one of the best options available to a web developer when they find themselves responding to questions like - "Does your webapp have a predictable state?" - with answers like - "Given ample time and resources, I can predict it with a fair amount of certainty". It came in at a time when developers using Flux libraries started getting frustrated with the boilerplate code involved in getting it going. Redux was heralded as a champion when it took center stage retaining the best things from flux architecture and doing away with majority of the boilerplate. But lately it has been drawing flak for the exact same crimes that it's predecessors were charged with - "too much boilerplate", "complex to configure" etc. The image below highlights those facets of Redux that have gained notoriety amongst the renegade faction along with the crimes that they have been accused with. A multitude of tools have been devised(redux-toolkit, rematch) with the express intention of putting an end to these issues.
Being a developer who has worked on pre-Redux state management, I've rarely been frustrated with the the above aspects of Redux that people generally complain about. I was more frustrated about the sheer volume of repetitive code that I had to write on a daily basis to do mundane state operations
- Extracting a value from the action object and assigning it to some part of the state
- Appending, deleting, editing a value in an array
- Switching on/off boolean flags
As the application grows bigger, so does the state and along comes the problem of writing, testing and maintaining the complex state logic embued in a plethora of reducers. Reducer factory is an attempt at mitigating some(eventually most) of these troubles by delegating some day to day state operations(like the ones listed above) to a configuration and write reducer code only where complex logic is warranted.
Use case
Consider a user profile page that has the following fields
name
- Name of the userenabled
- A boolean field that determines whether the profile is enabled or notemail
- Email of the usergender
- Gender of the useroptions
- An array of options selected by the userdialogOpen
- Denotes whether the dialog to save the user details is open or not
The actions to the store are in the following format
The task is to write a reducer that honors the following actions
PROFILE_FETCHED
: Fills all fields from the payload with transformation applied to the fieldsenabled
,options
andgender
ENABLED
: Turns on theenabled
flagDISABLED
: Turns off theenabled
flagNAME_CHANGED
: Setsname
fieldEMAIL_CHANGED
: Setsemail
fieldGENDER_CHANGED
: Setsgender
field with lower case transformationOPTION_SELECTED
: Appends an option to theoptions
arrayTOGGLE_CONFIRMATION
: Toggles thedialogOpen
flagCLEAR_FORM
: Clears all the fields to defaults
Coded reducer
The reducer to achieve the above looks like this
Configured reducer
The entirety of the above reducer can be reduced to a JSON configuration using reducer-factory
If an action warrants the use of explicit coding, the above config can be extended with a reducer through which the action will be passed after it has been run through the config. If there is a piece of custom app specific state logic that is being used across multiple reducers, reducer- factory also allows for defining this logic as a custom state operation which can then be used in reducer configurations throughout the app.
The library still has a long way to cover before it can confidently claim to have ridden all mundanity in the life of a web developer with regards to reducer coding. But I believe the ability to configure the aforementioned 3 operations goes a good way in removing the bulk of state operations in most applications. At least, it did so in all of our webapps.