After completing my basic implementation of render functions, I went further to tap into Reactive Programmming using JavaScript.
import { reactive } from "../lib/index.js"
// App state
const state = reactive({ count: 0 })
// track `count`
watchEffect(() => console.log(`Count: ${state.count}`))
// increment
++state.count
// > Count: 1
++state.count
// > Count: 2
Temperature Converter -> source code -> demo link
This repository is not for beginners; it's targeted at intermediate or professional developers and programmers who want to take their JavaScript skills to the next level.
Some of the basics (like loops, conditionals, and closures) are not discussed at all. If you find you need to brush up on some of those topics, refer to the MDN Web Docs
NB: Intermediate understanding of JavaScript and some of the latest ECMAScript Standards like classes, modules, shortcircuiting, and more.
Modern JavaScript Frameworks have different implementations on gaining reactivity; common usecases include DOM updates and App state.
I recommend that you check out how some modern frameworks implement reactivity; - Vue, - Solid, -Svelte
Warning: No application should be built on top of this Reactivity System as it is intended to be for learning or study purposes only.
My understanding of Reactive JavaScript is based on the idea that when the variable changes, all computations that depend on it get re-evaluated.
Example: Spreadsheets like Microsoft Excel use cell referencing such that if cell A3 is the sum of cells A1 and A2, then whenever cell A1 or A2 changes, the value of cell A3 gets re-evaluated.
The naming of the building blocks is based on Vue's Reactivity.
watchEffect
A function that opens a subcription to reactive values and so saves the action to be notified when updates occur
Takes an action
as an argument
Interface
watchEffect(action: function)
We can watch all reactive value like ref
, computed
and properties of reactive
objects
How does watchEffect
work, check it out here
ref
A function that creates a reactive object from a primitive value either string, number or null
Takes any primitive type and return a object with the value
property
Interface
const variable_name = ref(value: string | number | null | undefined)
Example
import { ref } from "../lib/index.js";
// first name
const firstName = ref("Brad")
// read value
console.log(`My first name is ${firstName.value}.`)
// watch firstName for changes
watchEffect(() => {
console.log(`Your first name has changed to ${firstName.value}`)
})
// change value
firstName.value = "Henry"
// change again
firstName.value = "John"
How does ref
work, check it out here
computed
A function that stores a value that re-calculates when it's dependencies get updated.
This is used in conjuction with other reactive values like
ref
,reactive
Takes a function as an argument and returns an object with only a getter for a value
property
Interface
const variable_name = computed(action: function)
Example
import { computed, ref, watchEffect } from "../lib/index.js";
// cells A1 and A2
const A1 = ref(1),
A2 = ref(2)
// cell A3 - computed sum
const A3 = computed(() => A1.value + A2.value)
// watch cell A3 for changes if either cell A1 or A2 changes
watchEffect(() => {
// read A3
console.log(`A3 is ${A3.value}`)
})
// change cell A1
++A1.value
// logs > A3 is 4
// change cell A2
A2.value = 5
// logs > A3 is 7
How does computed
works, check it out here
reactive
A function that creates a reactive object from only objects not arrays.
Takes an object
as argument and returns a proxy
Access of properties does not behave like
ref
orcomputed
, they are accessed directly and still reactive.
Interface
const variable_name = reactive(obj?: any)
Example
import { reactive } from "../lib/index.js";
//app state
const state = reactive({ count: 0 })
// read a property
console.log(`Count: ${state.count}`)
// logs > Count: 0
// change `count`
++state.count
// read a property
console.log(`Count: ${state.count}`)
// logs > Count: 1
Note: Destructing objects causes a disconnection from reactivity since the properties are referenced in objects and so destruction assignment to a variable de-references the property from the reactive object
How does reactive
work, check it out here
Source code contains comments that take you through what happens behind the scenes
To build it from scratch as you test each of the building blocks, check out the source code.
I have developed some basic examples to illustrate how reactivity can be useful.
import { ref, computed, watchEffect } from "../lib/index.js"
// count
const count = ref(0)
// double
const double = computed(() => 2 * count)
// watch `count` and `double` for changes
watchEffect(() => {
console.log(`Count: ${count.value}, Double: ${double.value}`)
})
// trigger changes
++count.value
// logs > Count: 1, Double: 2
++count.value
// logs > Count: 2, Double: 4
++count.value
// logs > Count: 3, Double: 6
In case of any issues or inquiries about this, a pull request is welcome.
Thanks.