Reactive programming & web frameworks
In recent years we have seen a strong development of tools based on the principle of reactivity, especially in the construction of interactive user interfaces. This concept, although quite widespread nowadays, can remain vague for some. The aim of this article is to present, in broad outline, what the principle of reactivity is, especially in the design of user interfaces.
In recent years we have seen a strong development of tools based on the principle of reactivity, especially in the construction of interactive user interfaces. This concept, although quite widespread nowadays, can remain vague for some. The aim of this article is to present, in broad outline, what the principle of reactivity is, especially in the design of user interfaces.
Reactive programming, what is it?
The principle of reactivity is a concept in computer science that refers to the idea that a system should be designed to respond to changes in its environment quickly and appropriately. As mentioned above, this principle is often applied to the design of interactive software systems, such as user interfaces, which must respond to user actions or other external events in real time.
More technically, the goal is to propagate changes of a reactive element (which can be a variable, a user input, etc.) to other elements that depend on it.
This description may sound familiar to some, since it is reminiscent of a very common design model: the Observer model. Indeed, the concept of reactivity is based on this principle.
Key Concepts and Benefits of the Reactivity Principle
The principle of reactivity has three key concepts:
- Change detection, for a system to be reactivity, it must be able to detect changes in its environment. These can be user inputs, internal variables, external sources, or other types of events.
- Reaction to changes, once a change has been detected, the system must be able to respond quickly and appropriately. This may include updating a display, performing a calculation, etc.
- Feedback, the system must provide feedback to the user or other parts of the system to indicate that a change has been made and what the result was.
Reactive programming has many benefits. Among them, we find in particular:
- The reduction of the risk of bugs linked to the forgetfulness of variable updates.
- A more manageable triggering order for events.
- Building more interactive and fluid user interfaces.
- A code, especially when the applications start to become large, much simpler and more maintainable.
To illustrate these advantages, let's compare two identical functionalities (a counter), one written in native JavaScript, the other using a reactive framework.
First in native JavaScript:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="src/style.css">
</head>
<body>
<button id="increment-counter-button">Increment counter</button>
<button id="decrement-counter-button">Decrement counter</button>
<div>
Result :
<span id="counter-result"></span>
</div>
<script src="src/script.js"></script>
</body>
</html>
// src/script.js
let counter = 0;
const incrementButton = document.getElementById('increment-counter-button');
const decrementButton = document.getElementById('decrement-counter-button');
const resultContainer = document.getElementById('counter-result');
// fonction d'affichage du résultat du compteur
function displayCounterResult() {
resultContainer.innerText = counter;
}
// on affiche une première fois le compteur, avec sa valeur par défaut : 0
displayCounterResult();
// au clic, on incrémente de 1 le compteur et on affiche le résultat
incrementButton.addEventListener('click', function() {
counter++;
displayCounterResult();
})
// au clic, on décrémente de 1 le compteur et on affiche le résultat
decrementButton.addEventListener('click', function() {
if(counter > 0){ // on empêche des valeurs négatives
counter--;
}
displayCounterResult();
})
The same thing with a reactive framework (Vue) :
<script setup>
import { ref } from 'vue';
// on initialise simplement la variable réactive ici
const counter = ref(0);
</script>
<template>
<button @click="counter++">
Increment counter
</button>
<button @click="counter > 0 ? counter-- : null">
Decrement counter
</button>
<div>
Result :
{{ counter }}
</div>
</template>
With both methods, the result is the same:
By looking at the differences in the code, we can see that some frameworks, like Vue, do not require us to manually select DOM (Document Object Model) elements to manipulate them. We just have to manage our reactive variables. Moreover, for the display, there is no need to have a function to change the text. As soon as the variable changes, the framework detects it and directly updates the DOM with the new value.
We can see that even for such a small feature, the code provided is already less important with a reactive framework. So, imagine for large-scale apps.
Reactive JavaScript frameworks
They were mentioned earlier, but what is a reactive framework ? They are frameworks that provide tools and abstractions to detect and react to changes in the state of the app, making it easier for developers to build reactive systems. Let's take a look at the most common ones or the ones you should know at the moment concerning front-end.
The Vue framework
Vue.js is a progressive JavaScript framework for building web apps. It is designed to be lightweight, easy to learn and easy to use. In particular, the framework allows you to create reusable components in a simple and efficient way.
One of the main features of Vue.js is its templating syntax, which allows you to define the structure of your user interface using a simple and expressive syntax. Vue.js also provides a set of tools for managing state and rendering components, including a virtual DOM to optimize the rendering of UI elements. When the state is updated, it calculates the difference and modifies only the parts affected by the update, not the entire DOM.
One of the main differences between Vue.js and other frameworks is its emphasis on simplicity and ease of use. It has a low learning curve and is well suited for small to medium-sized apps. Note that it is very suitable for larger applications. It is also lighter than other frameworks, which can be beneficial for performance, especially on mobile devices. By the way, this is a framework that we have adopted and use at Atipik. In another article we share our tips and best practices for developing with Vue if you are interested!
The React framework
Developed by Facebook and often used to build SPA (Single-Page Applications), React allows, like Vue, to create reusable components in a simple and efficient way. React is also based on the Virtual DOM, which allows it to achieve good performance. It is also suitable for all types of applications, especially small and medium.
One of the key features of React is its declarative approach to programming. You describe what you want the user interface to look like, and React takes care of the rest. This makes it easier to build and maintain a complex UI, because you don't have to worry about low-level details like DOM manipulation.
React also has a large and active community, with many third-party libraries and integrations available. It is often used in combination with other libraries like Redux to manage the state of the app, and React Router to manage routing.
The Angular framework
Angular is an open source framework based on TypeScript and developed by Google, which allows it to have an equally large community. It is designed to make building front-end apps easier, by providing a whole set of tools and frameworks.
It provides a set of built-in services for common tasks such as HTTP request creation, form validation and routing. In addition to the core Angular framework, the Angular ecosystem includes a number of libraries and tools for building modern web apps, including the Angular CLI for project generation and management, Angular Material for implementing material design, and AngularFire for integration with Firebase.
Its main strength can also seem like a flaw depending on the use. As we have just seen, Angular is much more robust than its colleagues React and Vue, with many built-in libraries and features, but is at the same time much heavier. It is therefore rather advisable to use it in the context of very large projects.
The Svelte framework
Svelte is a relatively new framework, but it has gained popularity in recent years because of its approach to building web apps.
One of the main differences between Svelte and other frameworks is that it does not use a virtual DOM. Instead, it compiles the code at build time, generating optimized JavaScript code that updates the DOM directly. This means we don't have to pay the performance cost of updating a virtual DOM at runtime, which can make Svelte apps faster and more efficient.
Svelte uses a template syntax similar to HTML, with additional features to bind data and control component behavior. It also provides a way to manage state and handle side effects using stores and reactive statements.
Svelte is lightweight, which is suitable for developing small to medium-sized apps. It has a growing community, with a number of third-party libraries and integrations available.
The Riot.js framework
Riot.js is also a lightweight JavaScript library. It was created as an alternative to larger frameworks, with an emphasis on simplicity and ease of use.
The framework uses a template syntax similar to HTML, with additional features for binding data and controlling component behavior.
One of the key features of Riot.js is its small size and minimal dependencies. It is only a few kilobytes in size, making it suitable for use in resource-constrained environments. It's also easy to learn, with a simple API and a focus on flexibility.
As you can see, like Svelte, Riot.js is suitable for building small to medium-sized apps. It has a growing community, as well as a number of third-party libraries and integrations available.
The Alpine.js framework
You thought that Riot.js was already very light ? Well Alpine.js does even better! This library composed of 15 attributes, 6 properties and 2 methods, is certainly one of the most minimalist tools of all.
Indeed, its ultra-simplistic use, via attributes directly placed on markups, allows the development of reactive functionalities very quickly and simply. Diving into Alpine is a formality once you understand the principle of reactivity and components. It is certainly the best tool to start with.
Now, unlike heavy frameworks such as Angular, Alpine.js will only really be suitable for small use cases.
In summary, the principle of reactivity is a concept that emphasizes the importance of building systems that are able to detect changes in their environment and react to them effectively and appropriately, in order to create the most interactive and fluid user experience possible.
It is therefore necessary to make a thoughtful choice of the framework to be used, depending on the needs and use cases. In addition, it is important to use reusable components for a better code organization. To be continued ...
Jérémy
Software Engineer · Web