Simplest Reactivity in Web Pages Using Vanilla JavaScript;
Tags: reactivity, webdev, javascript, html
Published: 2023-10-04 18:20:06

## **Introduction:**
> Reactivity is a key feature in modern web development, allowing for dynamic updates to the user interface based on changes in data or state. While frameworks like React, Vue, and Angular provide powerful tools for building reactive applications, it's also possible to implement reactivity with vanilla JavaScript. In this article, we'll explore how to build reactive HTML pages using only JavaScript, starting from scratch.

### **Step 1: Creating Reactive Values**
To begin, we need a way to create reactive values in our application. These values will be the foundation of our reactive system, allowing us to track changes and update the UI accordingly. Here's a simple implementation of a reactive value:
```javascript
function reactiveValue(initialValue) {
 let value = initialValue;
 const subscribers = [];

 function get() {
    return value;
 }

 function set(newValue) {
    if (value !== newValue) {
      value = newValue;
      subscribers.forEach((subscriber) => subscriber());
    }
 }

 function subscribe(subscriber) {
    subscribers.push(subscriber);
 }

 return { get, set, subscribe };
}
```
This `reactiveValue` function takes an initial value and returns an object with three methods: `get`, `set`, and `subscribe`. The `get` method simply returns the current value, while the `set` method updates the value and notifies any subscribed functions. The `subscribe` method allows us to register a function that will be called whenever the value changes.

### **Step 2: Creating Reactive Attributes**
Next, we need a way to attach these reactive values to HTML elements. One approach is to create a custom attribute that we can add to any element. Here's an example of how we might define a `data-reactive` attribute:
```html
<div data-reactive="name"></div>
```
We can then use JavaScript to retrieve the value of this attribute and create a reactive binding between the element and the corresponding reactive value. Here's an example of how we might implement this:
```javascript
const reactiveElements = document.querySelectorAll('[data-reactive]');

reactiveElements.forEach((element) => {
 const name = element.dataset.reactive;
 const value = reactiveValue(null);

 // Set up a subscription to update the element when the value changes
 value.subscribe(() => {
    element.textContent = value.get();
 });

 // Update the value when the element changes
 element.addEventListener('input', (event) => {
    value.set(event.target.value);
 });
});
```
In this example, we first select all elements with a `data-reactive` attribute using `document.querySelectorAll`. We then iterate over these elements and extract the name of the reactive value from the attribute. We create a new reactive value with the initial value of `null`, and set up a subscription to update the element whenever the value changes. Finally, we add an event listener to update the value whenever the element changes.

### **Step 3: Creating Reactive Expressions**
While reactive attributes allow us to bind individual elements to reactive values, we often want to perform more complex operations involving multiple values. To handle this, we can create reactive expressions, which are functions that take one or more reactive values as inputs and produce a new reactive value as output. Here's an example of how we might implement a simple reactive expression:
```javascript
function reactiveExpression(fn, ...values) {
 const result = fn(...values.map((value) => value.get()));
 const dependencies = values.filter((value) => value instanceof ReactiveValue);

 const reactiveValue = reactiveValue(result);

 dependencies.forEach((dependency) => {
    dependency.subscribe(() => {
      reactiveValue.set(fn(...dependencies.map((value) => value.get())));
    });
 });

 return reactiveValue;
}
```
This `reactiveExpression` function takes a function `fn` and one or more reactive values as arguments. It calls `fn` with the current values of the input reactive values, and creates a new reactive value with the result. It then sets up subscriptions to update the output reactive value whenever any of the input reactive values change.

Here's an example of how we might use `reactiveExpression` to create a reactive expression that calculates the sum of two reactive values:
```javascript
const a = reactiveValue(1);
const b = reactiveValue(2);
const c = reactiveExpression((x, y) => x + y, a, b);
```
In this example, we create two reactive values `a` and `b` with initial values of 1 and 2, respectively. We then create a reactive expression `c` that adds `a` and `b` together, using the `reactiveExpression` function. Whenever either `a` or `b` changes, the `c` reactive value will be updated automatically.

## **Conclusion:**
Building reactive HTML pages with vanilla JavaScript involves creating reactive values, attaching them to HTML elements, and combining them using reactive expressions. By following these steps, we can create robust and scalable reactive systems without the need for large frameworks. Whether you're building a simple form