DEV Community

Cover image for Simplest Reactivity in Web Pages Using Vanilla JavaScript;
ArnavK-09
ArnavK-09

Posted on • Updated on

Simplest Reactivity in Web Pages Using Vanilla JavaScript;

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:

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 };
}
Enter fullscreen mode Exit fullscreen mode

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:

<div data-reactive="name"></div>
Enter fullscreen mode Exit fullscreen mode

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:

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);
 });
});
Enter fullscreen mode Exit fullscreen mode

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:

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;
}
Enter fullscreen mode Exit fullscreen mode

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:

const a = reactiveValue(1);
const b = reactiveValue(2);
const c = reactiveExpression((x, y) => x + y, a, b);
Enter fullscreen mode Exit fullscreen mode

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

Top comments (2)

Collapse
 
artydev profile image
artydev

Nice, thank you

Collapse
 
bytebricks profile image
ByteBricks.ai

I love the approach, we use vanilla JS sometimes, such approaches are great insight!