Disclaimer
Dear reader! If you do not have a clue what React and Redux are, read further does not make sense, further technical nonsense. I seriously, understanding what this note is for, requires working with these libraries - although I will try to write clearly, this article is not an entry level. And this is a personal experience and opinion based on practice.
What is wrong with using Redux?
Then I decided to write, but what exactly is wrong with using redux in my project and thousands of others? I’m writing applications on react / redux commercials since April 2016 (three years). It’s time to open some interesting things ... And then there were lectures and reports, especially those aimed at beginners, but there wasn’t any adult look back and there were no retrospectives. In the meantime, someone puts asterisks to packages that check “and not 13 if you are an hour,” I will break the wall of existing stereotypes.
But redux is not needed!
You will say and in something you will be right. It can not be used from 2018 - a ton of articles on this topic on the Internet, but as long as the collective farm is “not being used”, it will be clear below why. And so many alternatives rolls over and even more.
We use Redux, because this is an accepted standard (at least for react), the predictability and reliability that Redux has is important to us. But we seriously lose it, actually in this
')
Claim
Probably, to make it clear what the claim is on the points, you must first return to the past, to the sources, as you like, namely, to open the documentation of the glorious redux and read the postulates. I will consider only the first one. If you are interested, share in the comments, sort out many more moments.
The only source of truth ...
Here we have an ambush. Of course, it says that there may be 1 stor, redux declares its difference from the flux architecture in this way. But if you look wider: is the rule respected in a real project? You say: completely. I declare (declare) 1 stor, transfer it to the provider and then ...
Technically, the process describes correctly. But I can say that people are prone to distortions of perception, logic, and since programmers are still people ... Well, you understood what I am leading to (if they did not understand: programmers are prone to distortions of perception, logic, etc.)
The main distortion here is that I, like many of my colleagues, are used to the fact that if we don’t use the term “store” in relation to anything other than redux, then there is no other store.
And here comes the reactor
One technical feature, which is called internal state, wanted to spit on this postulate. It simply creates an internal state store at any convenient place. There is a component - there is a state that has a mechanism for updating and influencing the component. The difference in terms of use (to keep state, update and broadcast changes) is almost imperceptible. You can argue: it is not clear what you do not like the state of the component. He is not the same as redaks, how can they be compared at all! It is internal, well, there are some flags to keep.
Understand that the essence does not change from the fact that you rename the subject. There is a sledgehammer Monday, it does not make it a day of the week. Yes, both Mondays are heavy, other days and sledgehammers are easier. But from its name a sledgehammer does not cease to be a percussion instrument.
The scale of redux and state react-component is different, but the essence, with their current use, is the same.
I will explain it this way: in the overwhelming majority of cases, the data from the internal state of the child get into the children through props, but no matter how obvious it may sound — redux data, when integrated with react, also get into the components via props. From the point of view of the component that takes props - no matter what's outside. That is, for the end user - that redux store, that internal state - is the same.
Also, this internal state may not depend on the props of the component in which it is declared. Then isolation turns out, which makes such an internal state an even bigger store than can be imagined.
In order for it to be internal, it only has to influence the component where it is declared, without giving leaks to the child components. Complicated? Very, because its meaning is almost completely lost. This is another sign that the internal state is a store. After all, we simply removed one item from the “keep state, update and broadcast changes” destination — translation of changes. That's all, stey lost.
That is, the main problem of having an internal state is that it competes with redux for data, loses in the long run and shatters. We have all sorts of lift state up techniques (this is when the host element sibling data is needed, so part of the state and all the logic of working with it is passed to the parent, spending a lot of time rewriting and testing the working logic), etc. Bugs appear, overhead in the improvements and a lot of joy. This is all the noise that spoils our software at the development stage. We have not sunk to the market, but the software is already such.
That is, according to all signs and problems, we have more than one story and many problems associated with it. The final thing will probably be the following:
I really love redux also for the kind of devtools he has. When I started we used a logger, which simply consolidated all the actions, without giving, however, a complete picture of what is happening. Now - this is the main assistant and friend. At React they are also represented. In general, devtools is the reason why any pubsub is far from Redux. Like an ant to a blue whale.
Problems (there will be no proofs - DNA):
- changing internal state through react devtools sometimes does not lead to an update or the desired result - I sin on integration with redux.
- internal state breaks timetravel in redux devtools. The super feature with time travel, available thanks to the redux architecture, does not work thanks to the react internal state architecture. Internal state simply did not care about the change in redux, it has its own state. Timetrevel just does not come out. Some of the elements are simply not updated, partially updated, etc. The whole epic is in sync with the asynchronous code down the drain.
An example, of course, sucked from practice
You are working on a new project for you, or your colleague wrote some functionality a year ago, and now you need to expand it. In general, there is a task to finalize someone else's code. You start to investigate, and understand that there is no data in the redox. In the code there are no actions, reduers that store the data you need. And you begin the journey through the tree of components in search of the cherished and find them (!!!) even a few pieces. You ask your colleagues, but the answer is standard: I don’t remember, we’d write to the state faster, we didn’t have time and so on. You go to the source and understand that its current state does not imply revision. You rewrite the working tested code to make changes and add new functionality.
The presence of a disastrous alternative in the form of an internal state does its dirty work. After all, now it is cheap, and it does not matter what will happen next year.
Little metaphor
It looks like bad food - it seems tasty and cheap, but after a year or 3 - the gastrointestinal tract ceases to obey and lives its own life. You spend a lot of time and money on the return of former health and not always succeed.
Redux and React Internal State are competitors , as a large and small business in one niche. The main commodity is data and influence. Software is a consumer of their products. Many analogies can be cited, but the essence remains the same - when we develop software, we do not need competition.
We are “dictators” of the program code and any competition should be stopped, the free market should be banned, and the planned economy and state monopoly should dominate the consumer.
Hmm, something has borne me. Everything should go according to plan, in general. We have sprints, releases, etc., and the software has a final cost and lifetime / market entry. This is very important, and we cannot allow a riot on the ship, the uprising of libraries.
The conclusion is simple
Do not use with redux other stores. Exceptions can make only very isolated cases. For example, components that, in principle, are not controlled by redux without a corresponding layer and do not affect it.
Example
I developed a standalone module in one branch and refactoring a store in another - in general my approach to managing the store and state is a separate topic for publication. I started refactoring before the module, but at the time of both the beginning and the end of writing the module, refactoring into the test and into the master did not go away. Refactoring is big and requires thoughtful regression that needs to be planned - in general, you can't just take and refactor.
Therefore, knowing about the upcoming changes in the store, I did not use it to develop a new feature. This would increase the cost of updating abandoned refactoring and tests at times.
What I did: subscribe to a minimum of data. The data and their structure did not suffer from refactoring, suffered the code that formed them, saved them, etc. I do not write a single byte in the redaction. Check if the user is logged in and a couple more fields.
For my needs, I wrote down PubSub with channels and a simple API. Yes, yes, pabsab. Lack of normal devulz pain. Time-travel - pain. In general, I plan to write an extension for chrome in the form of devtools and maybe publish on the github re-implementation as a competitor redux. I have a ton of claims to redux, which I will not raise in this article, but there is practically no such PubSub. In addition, I remembered the redux logger ...
And so the module has its own storage, its connection to the server.
That is, redux does not affect the module at all, practically has no effect on this storage (there are only three fields in the subscription), but neither the module nor the PubSub has any effect on redux. This separation excludes concreting.
The question “where to store data?” When developing a module, I never had one. But when it comes to redux vs internal state - for many this question arises almost constantly. I decided to answer this question once and for all.
My architectural opinion is:
Store data only in redux (everything, even “internal”), if it is connected to your react-project as the main repository, do not use repositories that will compete with it. This will increase the reliability and impact of this library and its devtools (time-tracking and tracking all the data in steps accelerates the development and search for possible problems - synchronous changes debugging are steeper and simpler than asynchronous).
Perhaps you should add a library that completely excludes the internal state from development? Or replaces internal state with a sample of redux, for example? I started writing one such a year ago, I finished 90 percent, I even gave 1 lecture. What do you think? Looking for such?
I hope you liked this note :)