It turned out that at the moment I am taking part in the development of front-end applications (React + Redux), which makes many requests to the REST API every minute, if not a second.
I am tired of writing REQUEST / FAILURE / SUCCESS (hereinafter referred to as RFS) for each request, action cases for them, and all of this is a case for a reducer.
I wrote another bike.
A lot of libraries have already been written for convenient work with RFS, but they presuppose a detailed setting of each of the three actions + writing case for a reducer + tests. Basically, these libraries can be used in 100% of the time of writing requests to the server. This flexibility requires writing a lot of code for tasks of the same type.
In the project that I am currently involved in, 90% of the requests perform an extremely simple task: go to the server, take the data, convert them a little, put them in the state , if something went wrong - complain. Thousands of lines of tests are written, which in essence are copy-paste with micro-changes.
How long? Weekend in front of the monitor, a liter of coffee, shavarma for lunch and dinner, a little controlled magic ...
... the library is ready.
The fromTo function (from, to, [through]) takes the data where it is said, converts it as it should and puts it in the specified place (any in your state , but only if you use the immutable library for the reducer). The reducer independently (after wrapping it in fromTo.wrapper
) will understand how to work with the data and predictably change the state in accordance with the RFS actions (which the library will take care of itself). Everything is covered with tests (if you find bugs, push it down or open the ticket ).
The simplest way (about half of the cases on our project) of using fromTo action is:
// {"mood": "happy"} , HTTP200 dispatch(fromTo( () => axios.get('dogs.io/good-boy'), ['dogs', 'goodBoy'], ));
This is what will happen in your state at this time:
Initial state
{ ...otherReducers, dogs: Immutable.fromJS({}), }
REQUEST
{ ...otherReducers, dogs: Immutable.fromJS({ goodBoy: { isRequesting: true, }, }), }
SUCCESS
{ ...otherReducers, dogs: Immutable.fromJS({ goodBoy: { isRequesting: false, data: { mood: 'happy', }, }, }), }
For another 40% of cases, an object is used as an argument to
and a third (optional) argument is added. In eastern cases, we act in the old manner ( fromTo
not a panacea, but a handy tool).
fromTo(from, to, [through])
The function has 3 arguments.
from
. We say where to get the data. The function that the Promise returns. It will be called without arguments.
to
. We say where to save data.
{ request, failure, success }
. These are the 3 coordinates for the data in your state , where they will be saved:request
: coordinates for a boolean whether the from
call is completed (for example [ 'dogs', 'isFetching', 1 ]
)failure
: coordinates for the data that returned during reject
(for example [ 'cats', 'errors', 2 ]
)success
: coordinates for the data that returned at resolve
(for example, [ 'robots', 'data', 3 ]
).[ 'goodBoy' ]
), then this argument will be converted to the object { request: [ 'goodBoy', 'is Requesting' ], failure: [ 'goodBoy', 'error' ], success: [ 'goodBoy', 'data' ] }
[through]
. We say (and we can not speak and trust the defaults), how to convert the data that came back from()
result. An object can contain one or both of the methods:requestAdapter
is a function that receives input from resolve
. Returned data will be saved with SUCCESS,errorAdapter
is a function that receives input from reject
. Returned data will be saved with FAILURE.At the moment, on the project, we are saving hours of our time and bundles of nerves due to the lack of the need to write tons of uniform code. Instead of 90% of actions, reducers, tests, one dispatch(fromTo(...args))
function is called dispatch(fromTo(...args))
. We are glad.
Of course, a number of tests are still being written, but mostly they are tests for the through
argument (mandatory) and the TDD tribute.
In the comments I would like to see the opinion of colleagues in the workshop, constructive criticism is more than welcome. Raw in gita , library in enpeeme , duck in a hare, hare in a chest, and that on tree.
Have a nice day.
Source: https://habr.com/ru/post/336202/
All Articles