-
Notifications
You must be signed in to change notification settings - Fork 0
Summary: Example Usage
Appurist (Paul) edited this page Sep 26, 2020
·
1 revision
The following example illustrates how to use the reactivator library package, and its JavaScript API.
Note: This is a "kitchen sink" example which includes a bit of almost everything, so it is quite noisy; see examples within each specific function for examples suitable for those functions, which make for easier reads.
The resulting output is also provided below the source code sample:
import { ref, reactive, computed, isRef, isReactive, isComputed, watch, unwatch, dumpValue } from 'reactivator';
// This is a richer "kitchen sink" example of the functions available from the reactivator package.
let state = {
test1: ref(5),
test2: ref('Hi there'),
test3: reactive({textField: 'Hello', numField: 42})
}
console.log("isRef(test1):", isRef(state.test1));
console.log("isReactive(test1):", isReactive(state.test1));
console.log("isRef(test3):", isRef(state.test3));
console.log("isReactive(test3):", isReactive(state.test3));
// define a computed reference based on state.test1 and an addOne function
function addOne(context) {
return context.value + 1;
}
let computedAddOne = computed(state.test1, addOne);
console.log("isComputed(state.test1):", isComputed(state.test1));
console.log("isComputed(computedAddOne):", isComputed(computedAddOne));
// define a computed reference based on state.test3 and a combineFields function
function combineFields(context) {
return context.textField + ' #' + context.numField;
}
let computedCombine = computed(state.test3, combineFields)
watch(state.test1, (old, val) => {
console.log(`watch: test1.value changed from ${dumpValue(old)} to ${dumpValue(val)}`);
console.log(`watch: computed addOne(test1) is now ${dumpValue(computedAddOne.value)}`);
})
state.test2.value = 'Hello'; // no watch installed yet, we'll miss this one
// save the watch so we can unwatch later
let saved = watch(state.test2, (old, val) => {
console.log(`watch: test2.value changed from ${dumpValue(old)} to ${dumpValue(val)}`);
})
// Let's define a more complex watch handler for object and array changes
// This is an ugly function provided to show how powerful the parameters are in the watch callback.
// Note dumpValue returns the text representation of strings as strings, arrays as arrays, etc.
// See the output below for the end result of this function.
function onChangeTest3 (old, val, prop, name, obj) {
let label = name ? `test3${name}` : 'test3';
if (Array.isArray(obj) && prop === 'length')
console.log(`watch: ${label}.${prop} changed to ${dumpValue(val)}`);
else
if (Array.isArray(obj) && parseInt(prop))
console.log(`watch: ${label}[${prop}] changed from ${dumpValue(old)} to ${dumpValue(val)}: ${dumpValue(obj)}`);
else
if (old !== undefined)
console.log(`watch: ${label}.${prop} changed from ${dumpValue(old)} to ${dumpValue(val)}`);
else
if (Array.isArray(val))
console.log(`watch: ${label}.${prop} assigned a new array ${dumpValue(val)}`);
else
if (typeof val === 'object')
console.log(`watch: ${label}.${prop} assigned a new object: ${dumpValue(val, true)}`);
else
console.log(`watch: ${label}.${prop} assigned value ${dumpValue(val)}`);
console.log(`watch: computed combineFields(state.test3) is now ${dumpValue(computedCombine.value)}`);
}
//////////////////////////////////////////////////////////////////////////////
// Now that the watches are in place, make a couple of changes with numbers.
state.test1.value = 6;
state.test1.value++;
//////////////////////////////////////////////////////////////////////////////
// Repeat a couple of changes with strings
state.test2.value += ' world';
// We should only see the change notification above for "Hello world", not "Goodbye!"
unwatch(state.test2, saved);
state.test2.value = 'Goodbye!'; // no watches, this one is missed
//////////////////////////////////////////////////////////////////////////////
// Now repeat with an object
state.test3.numField = 99; // no watch installed yet
watch(state.test3, onChangeTest3); // now install the watch
state.test3.numField = 100;
state.test3.field3 = 'completely new';
state.test3.textField = 'Goodbye';
state.test3.emptyArray = [ ];
state.test3.newArray = [ 'one', 'two' ];
state.test3.newArray.push('three');
state.test3.sub1 = { sub1a: 'value1a', sub1b: 'value1b' };
state.test3.sub1.sub1b = 'new1b';
unwatch(state.test3, onChangeTest3); // now uninstall the watch
state.test3.numField = 101; // this change will be missed
The above code produces the following output:
isRef(test1): true
isReactive(test1): false
isRef(test3): false
isReactive(test3): true
isComputed(state.test1): false
isComputed(computedAddOne): true
watch: test1.value changed from 5 to 6
watch: computed addOne(test1) is now 7
watch: test1.value changed from 6 to 7
watch: computed addOne(test1) is now 8
watch: test2.value changed from 'Hello' to 'Hello world'
watch: test3.numField changed from 99 to 100
watch: computed combineFields(state.test3) is now 'Hello #100'
watch: test3.field3 assigned value 'completely new'
watch: computed combineFields(state.test3) is now 'Hello #100'
watch: test3.textField changed from 'Hello' to 'Goodbye'
watch: computed combineFields(state.test3) is now 'Goodbye #100'
watch: test3.emptyArray assigned a new array [ ]
watch: computed combineFields(state.test3) is now 'Goodbye #100'
watch: test3.newArray assigned a new array ['one','two']
watch: computed combineFields(state.test3) is now 'Goodbye #100'
watch: test3.newArray.2 assigned value 'three'
watch: computed combineFields(state.test3) is now 'Goodbye #100'
watch: test3.newArray.length changed from 3 to 3
watch: computed combineFields(state.test3) is now 'Goodbye #100'
watch: test3.sub1 assigned a new object: {"sub1a":"value1a","sub1b":"value1b"}
watch: computed combineFields(state.test3) is now 'Goodbye #100'
watch: test3.sub1.sub1b changed from 'value1b' to 'new1b'
watch: computed combineFields(state.test3) is now 'Goodbye #100'