One of the Angular core concepts is the update of a component’s DOM in case the framework detects changes in its fields used in the template binding expressions. This is very convenient since it allows changing the component’s view just by updating the corresponding fields without any direct manipulations with DOM. At the same time, Angular leaves the way of how the component’s fields are updated to a developer and that works well in some simple scenarios since developers can quickly create components which meet all necessary requirements without the need to introduce any additional abstractions. However, in more complex scenarios, it becomes obvious that the lack of restrictions on the component’s data changes, turns into a problem due to the increased number of side effects which makes the behavior of components less predictable.

There are also additional factors affecting the difficulty of maintaining a free-changing state:

Asynchronous operations

When a component is executing one or several asynchronous operations this means that there are several logical flows changing the shared state, and some synchronization efforts are required. For example, a component loads some data for an input parameter, but when the data is delivered the parameter might have already changed. The data is no longer relevant and, as a result, a new request should be initiated.

2. Component input parameters

In Angular the input parameters might change at any time and in any way (one-by-one or all of them simultaneously) and a well-developed component should correctly reflect the changes.

There is no doubt that Angular creators are aware of these issues, and since the beginning the use of reactive programming (more precisely — RxJs library) has been proposed to resolve them. However, in my opinion, the reactive programing is not always the best solution for typical UI tasks. It is focused on the events distributed over time, but in the majority of cases an immediate reaction to an occurring event is required, and there is another approach (for example used in React) which provides more elegant solution for the above described problem.

The idea of this approach is to separate the component and its data into two different types. In Angular it can be implemented as follows: almost all of the component fields need to be moved into a separate class and only one field left in the component — it is “state” whose type will be that separate class. All of the class fields are supposed to be marked as “readonly”, so the only possible way to change something in the component would be to create a new instance of the class (with changed fields) and then set the instance as component “state”.

A new state instance will be always created as a reaction on events that require the component state to be changed. They can be initiated by user (button click, value change etc.) or by the system (callbacks from setTimeout, “fetch” etc.) As a result, a component lifetime circle can be represented as a series of state instances: