2 minutes
Contact me

Reactivity in JS

context: I have been using Vue.jsfor a number of side projects and really enjoy working with it, I also use Knockout.jsa lot in work which uses a similar approach. I wanted to dive into the abstracted functionality a little deeper to help me understand the libraries I work with.

How do changes in state translate to changes in the DOM?

Let's start with a variable:

let a = 10

and another one:

let b = a * 10

the complete picture now looks like this:


let a = 10
let b = a * 10

We want b to always be 10 times of a. We now have a problem, when a changes b will not be aware of that change and not update, no matter what a is,b will always be the original value of a times 10.

This is a imperative and procedural implementation which does not solve the problem fully, what we need is an approach that is declarative and object oriented.

In an ideal world we would have a function that looked like this:


onStateChanged( () => {
   b = a * 10
})

This function would run every time a changes to update the value of b. So how do we implement this function? We can see that it takes a function that is then ran to set the new state.

jargon buster: a program is described as stateful if it is designed to remember preceding events or user interactions; the remembered information is called the state of the system.

react.png

This is an approach that React uses and why setState is always used to well.. set the state.

There is another way that involves taking the state object and converting it into a reactive object.

Our onStateChanged function will be renamed autorun why will become clearer as we move through the examples.

Let's implement a mini data observer and look at how Vue.js handles things.

first we need to define accessors using the Object.defineProperty() API. This will allow us later to get and set the current state.

convert.png

View the code

That seems to be working as expected, we have a few more parts to create. Later we will change the name to observe rather than convert.

We are going to create a dependency class that keeps track of the things our state depends on, it will also notify those that depend on it that it has changed.

dep.png

dep-2.png

View the code

This of course is not the complete picture and a simplified version of the general idea. Notice the wrappedUpdate. This is a little trick to ensure that the correct function is added to the subscribers list. As it is assigned to the activeUpdate which our dependency instance checks for in its depend method, we can ensure that what we add to the subscribers list is currently active.

Putting it all together:

3.png 3.2.png 3.3.png

View the code

Read through the code and play around with the state. You see it log out the changes.

You can read more about reactivity in Vue here.

This idea may change a little in up coming version of Vue. You can read more about it here.

Happy Coding!