This directory contains three examples demonstrating different reactive programming patterns using vanilla JavaScript.
These examples teach core reactive programming concepts without framework dependencies, showing the manual patterns that modern frameworks automate.
check-boxes.html, check-boxes.js)Pattern: UI automatically reacts to state changes - the background color is derived from checkbox states.
bind_checkboxes(result1)
bind_checkboxes(result2)
function bind_checkboxes(cb_group) {
var cb_list = []
cb_group.querySelectorAll('input[type=checkbox]').forEach(
cb => {
cb_list.push(cb);
cb.oninput = cb_handler;
}
)
function cb_handler() {
var ok = cb_list.every(cb => cb.checked)
cb_group.style.backgroundColor = ok ? 'lightgreen' : ""
}
cb_handler()
}
cb_handler function contains the logic (what should happen)cb_handler() can be called repeatedly and always
produces the correct result based on current statelightgreen background when
all checkedlightgreen background
only when all checkedLike a light switch that turns on only when ALL conditions are met.
multipliers.html, multipliers.js)Pattern: One value affects multiple outputs - demonstrates one-to-many reactivity and dependency graphs.
update_all_multipliers()
function update_all_multipliers() {
update_specific_multipliers(document.querySelectorAll('.specific_multiplier'))
}
function update_specific_multipliers(specific_multipliers) {
specific_multipliers.forEach(specific_multiplier => {
let value1 = parseInt(specific_multiplier.value)
let common_multiplier = find_input(specific_multiplier, 'common_multiplier')
let value2 = parseInt(common_multiplier.value)
specific_multiplier.nextSibling.nextSibling.querySelector('.multiplier_output').textContent =
`${value1} * ${value2} => ${value1 * value2}`
})
}
function find_input(input, className) {
for (; !input.classList.contains(className); input = input.previousElementSibling);
return input
}
function increment_multiplier(button, className) {
let input = find_input(button.parentNode, className)
input.value++
input.oninput()
}
common_multiplier affects multiple
specific_multiplier outputs. When the common value changes, all dependent calculations
update.increment_multiplier function shows the pattern:
input.value++)input.oninput())update_specific_multipliers() can be called with
any subset of multipliers, making it flexible for partial updates or full recalculations.Like a spreadsheet - change one cell, and all formulas referencing it recalculate automatically.
synchro.html, synchro.js)Pattern: Multiple inputs stay in sync - any one can be the source, all others follow.
var inputs1 = [input1, input2, input3]
var inputs2 = [input4, input5, input6]
sync(inputs1)
sync(inputs2)
function sync(inputs) {
for (var input of inputs) {
input.oninput = function () {
var value = this.value
for (var input of inputs) {
input.value = value
}
}
}
}
inputs1 and inputs2 are
independent - changes in one group don't affect the otherThese examples demonstrate the manual plumbing that modern frameworks automate. You explicitly:
Modern frameworks use language or compiler magic to eliminate boilerplate:
<script>
$: allChecked = checkboxes.every(cb => cb.checked)
$: background = allChecked ? 'lightgreen' : ''
</script>
The $: tells the compiler "this is reactive, regenerate when dependencies change"
const state = reactive({
checkboxes: [...],
background: computed(() =>
state.checkboxes.every(cb => cb.checked) ? 'lightgreen' : ''
)
})
| Example | Pattern | Direction | Use Case |
|---|---|---|---|
| Check Boxes | Derived state | One direction (data → UI) | Computing values from state |
| Multipliers | Computed dependencies | One-to-many | Shared state affecting multiple outputs |
| Synchro | Synchronized state | Bidirectional (peer-to-peer) | Keeping multiple inputs in sync |
Together, these examples form a complete introduction to reactive programming fundamentals.
This is a teaching collection showing reactivity without framework magic - the core concepts that underpin:
Understanding these manual patterns makes it easier to understand what frameworks are doing under the hood.