📜 ⬆️ ⬇️

The difficulties of working with Redux and their solution

image

Redux among us


This is one of the most popular state-manager`s .

It is easy to use, transparent and predictable. With it, you can organize the storage and modification of data. And if we assume that the action `s and reducer`s are part of redux` a, then we can say without exaggeration that he is the holder of all the domain logic (aka business logic) of our applications.

Is everything so rosy?


For all its simplicity and transparency, the use of redux `and has several disadvantages ...

The data in the state ` redux` and lies in a simple javascript object and can be obtained in the usual way, you just need to know the way .
')
But how do we organize this data? There are only 2 options: a flat list and a hierarchical model .

A flat list is a great option for an application in which there is only, for example, a counter ... For something more serious, we need a hierarchical structure. In addition, each level of data will have less knowledge than the previous one. Everything is logical and understandable, but the path to the data becomes complex .

Example
const dataHierarchy = { user: { id, name, experience, achievements: { firstTraining, threeTrainingsInRow, }, }, training: { currentSetId, status, totalAttemptsCount, attemptsLeft, mechanics: { ... }, }, }; 

Here the user key is stored under the user key, in particular achivements . But achievements do not need to know anything about the rest of the user data.

In the same way, a specific workout mechanic doesn’t need to know how many attempts a user has left - this is data training in general.


The presence of a hierarchical data structure and the absence of a modular approach to this data leads to the fact that in every place where this data is used, it is necessary to know the full path to it. In other words, it creates connectivity of the data storage structure and their display structures and leads to difficulties with the path refactor and / or reorganization of the data structure.

image

IDE magic does not help
We can say that now there are powerful IDEs that change paths with one command, but little can change several nested keys of an object or understand that part of the path lies in a variable.

Another difficulty is testing. Yes, a separate article is devoted to the documentation for redux testing, but now it is not about testing individual artifacts like reducer`s and action-creater`s .

Data, action`s and reducer`s are usually interrelated. And one tree of logically related data is often served by several reducer `s, which need to be tested, including together.

Add to this list the selector`s , the results of which depend in particular on the work of the reducer`s ...

In general, you can test all this, but you will have to deal with a pack of artifacts, connected only by logic and agreements.

And what to do if we invented a structure, for example, with user data, including lists of friends, favorite songs and something else, as well as the functionality to change them through the action ` s- reducer` s. Perhaps we even wrote a pack of tests for all this functionality. And now in the next project we need the same ...

How to make a cheap code?

image

Search for a solution


In order to figure out how to preserve the advantages of redux `a and get rid of the described shortcomings, you need to understand what depends on what in the data life cycle:


image

The controller in this case is an abstraction that processes both user actions and data changes in the store `s. It is not at all necessary for it to be a separate class, as a rule, it is spread over components.

Combine the entire redux zoo into a black box


But what if we wrap the action `s, reducer`s and selector`s in one module and teach it not to depend on a specific path for the location of its data?

What if all user `s actions, for example, will be performed by calling the instance method: user.addFriend (friendId) ? And the data obtained through getter: user.getFriendsCount () ?

What if we can import all user functionality by simple import ?

 const userModule from 'node_modules/user-module'; 

Conveniently? Especially considering that for this you do not need to write a bunch of extra code:
The npm package redux-module-creator provides all the functionality to create loosely coupled, reusable and tested redux modules .

Each module consists of controller `a, reducer` and and action`s and has the following features:


As a result, we get a black box that is able to manage its own data and has handles for communicating with external code.

At the same time, this is all the same redux , with its unidirectional data flow, transparency and predictability.

And since this is all the same redux and all the same reducer `s, you can build from them any structure that is required by the logic of the application domain.

Source: https://habr.com/ru/post/459460/


All Articles