📜 ⬆️ ⬇️

Redux as the heart of the front-end architecture of the Unified Frontal System

In the last article, we told how the front-end of the program was arranged in general, and discussed the technological stack. This article is devoted to the discussion of Redux - why we call it the heart of the architecture of the EFS.



At first, when we chose React as the key technology for our frontend, we experimented a lot with various flux implementations: we didn’t want to write our implementation. We looked at two implementations: alt and redux. Since redux promotes a functional approach to development, and in the state we had a lot of java-developers accustomed to object-oriented programming, in their opinion, alt turned out to be simpler. From a subjective point of view, he had a major advantage: alt contained the magic component AltContainer, which passed the Instance Store to the child component through Props. Initially, it worked perfectly: we have a small application, within which there are several stores that are not interconnected. However, as the functionality increased, we began to realize that this technology was erroneous for us and the application became huge and uncontrollable.

One truth to rule'em all


When we thought about how to implement the router in the application, we relied on react-router. On the backend, we then used Spring WebFlow and had the desire to make react-router friends with WebFlow. As a result, due to the peculiarities of the react-router implementation, we were unable to implement anything, but we saw how it was implemented. Active work began on our component, which eventually received the name SWFRouter: the backend told us the id of the form that we output to the page, and we conducted the data from the backend through a special field in the react-context. It so happened that not only we are experimenting with technology. Backend developers abandoned SWF in favor of their own development, called Workflow. What to do next - SWFRouter is no longer needed, a different solution is needed. We didn’t want to rewrite the current implementation much by going to a slightly modified version called WFRouter. However, he could not satisfy our ambitions. We needed a single source of truth that could guide us where to go next. No longer thinking of routers, we switched to a slightly different concept: no routers - only flux. We came to the conclusion that alt did not suit us to implement the general logic of the application, and we finally returned to redux.
')
About what redux is and how it works, there are already a lot of articles, but we’ll stop at a little introductory. Each time an action triggers, the corresponding reducer fires, returning a new state. Redux adheres to the immutable pattern, which allows you to return to any state of the application at any time. In addition, there is support for middleware, i.e. we can embed our functions in the state update process.

With redux, switching applications became simple: a special action sent data to the backend, which returned either the id of the following form, or the URL to the bundle for subsequent download. We develop applications for the workplace independently of each other, and when released, we transfer the assembled bundle for subsequent deployment. This is convenient because we can assemble a business process from individual applications created by different groups of developers.

Let's say we have a task scheduler. Clicking on the task, we get into the application that allows you to perform it. Having performed the necessary operations, we return to the scheduler and see that its state is similar to what it was before the transition. When we went to the task, we completely unloaded the scheduler from the memory, however, we saved its state in the persistent storage, which allowed it to be loaded again upon return. To do this, we used a special middleware, which gave us the state to save it later.

So how does the workplace work? We basically abandoned the idea of ​​using an iframe, since this creates overhead and the need for workaround in the case of pop-ups.

The workplace consists of several components: AppContainer is a component for asynchronous loading of AMD modules, UFSProvider is a component wrapper over the Provider component from the react-redux module, which creates a store and passes some set of reducer's to it to connect the entire architecture into a single whole. But first things first.

Appcontainer


Props



In the draft, the number of forms exceeded several thousand, and it would be a mistake to make it a monolithic application, since each form has its own development, testing and deployment cycle. AMD was chosen as a modular system: each project packs its own set of forms into an AMD-module, which is a React-component. With the help of SystemJS, the next application is loaded; when it is loaded, it returns a promise, which is passed to the AppContainer component. After loading, the application is drawn inside AppContainer, and the reducer special field of the loaded application passes the root reducer, which is responsible for the application logic and is passed as a property to the UFSProvider component.

UFSProvider


Props



As mentioned earlier, UFSProvider creates a store with pre-configured reducer. We do not create a separate store for each application, instead we provide a piece of the existing one. We divided the store logic into five components:




Each time an application in the AppContainer is replaced, the set of reducer's in the app is replaced. If necessary, the previously saved state is transferred to the initialState.

Tips


The cornerstone in many applications is incomprehensible to a simple user prompts, which the programmer wrote in haste. We strive to ensure that all the hints in the interface are clear to the user. To do this, we created a special admin panel for prompts. From our library of components we deliver a specific set of tips: block, pop-up and others. All of them at the library level are connected to the state, i.e. already wrapped in the connect function. It is enough for the developer to specify only the hint code, and the text itself will be picked up from the state. So how does it work? Each time we access the server, we check the presence of the hints field in the response, if it exists, we transfer the contents of this field to state and thus the “terminated” components will receive text instead of code.

Download multiple applications


Everything described above works fine when there is only one application on the page. But what to do when such applications must be simultaneously loaded two or more? At the same time, applications should be able to exchange data between themselves. For this case, we set up the UFSProvider in such a way that at each action the event goes to a common data bus. In addition, we pass the state application. This was made possible thanks to special middleware, which transmits action and state to a special object. Now we insert into the page several AppContainer pairs - UFSProvider and set some logic. Suppose application A must respond to application B event, for this, A subscribes to action B of application B and implements its own logic.

Perhaps this is the main thing that we wanted to talk about Redux technology in the Program. The main thing is not to be afraid of experiments and create such an architecture that is right for you.

We will be happy to talk about this and other current topics of front-end development in the comments to the article.

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


All Articles