-
Notifications
You must be signed in to change notification settings - Fork 0
Reactivator API: reactive()
Appurist (Paul) edited this page Sep 18, 2020
·
4 revisions
Parameters: (object)
Returns: a reactive version (copy) of the specified object
This method wraps a JavaScript data object with a new object that provides reactivity. It is similar to the reactive() function in the Vue 3 Composition API.
IMPORTANT: The returned value is a copy of the data, not the original data itself. All data access should be performed though the object returned, otherwise reactive observations may not generate for changes to the members.
import { reactive, watch, unwatch, dumpValue } from 'reactivator'
let state = reactive({field1: 42, field2: 'hello'})
function onStateChange(old, val, prop, name, obj) {
let context = name ? 'state'+name : 'state'
console.log(`${context}.${[prop]} has changed from ${dumpValue(old)} to ${dumpValue(val)}`)
}
state.field1 = 99; // no watch installed yet
// Let's define a more complex watch handler for object and array changes
watch(state, onStateChange)
state.field1 = 100;
state.field3 = 'completely new';
state.field2 = 'Goodbye';
state.emptyArray = [ ];
state.newArray = [ 'one', 'two' ];
state.newArray.push('three');
state.sub1 = { sub1a: 'value1a', sub1b: 'value1b' };
state.sub1.sub1b = 'new1b';
unwatch(state, onStateChange); // now uninstall the watch
state.field1 = 101;
state.field1 has changed from 99 to 100
state.field3 has changed from undefined to 'completely new'
state.field2 has changed from 'hello' to 'Goodbye'
state.emptyArray has changed from undefined to [ ]
state.newArray has changed from undefined to ['one','two']
state.newArray.2 has changed from undefined to 'three'
state.newArray.length has changed from 3 to 3
state.sub1 has changed from undefined to [object Object]
state.sub1.sub1b has changed from 'value1b' to 'new1b'
This example provides more accurate reporting of the changes, through the use of a more complex onStateChange
watch handler function. Also, when it detects the change is an object, it passes a true
to dumpValue
in order to have the value dumped as JSON:
import { reactive, watch, unwatch, dumpValue } from 'reactivator'
let state = reactive({field1: 42, field2: 'hello'})
// Let's define a more complex watch handler for object and array changes
function onStateChange(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)}`);
}
state.field1 = 99; // no watch installed yet
// Let's define a more complex watch handler for object and array changes
watch(state, onStateChange)
state.field1 = 100;
state.field3 = 'completely new';
state.field2 = 'Goodbye';
state.emptyArray = [ ];
state.newArray = [ 'one', 'two' ];
state.newArray.push('three');
state.sub1 = { sub1a: 'value1a', sub1b: 'value1b' };
state.sub1.sub1b = 'new1b';
unwatch(state, onStateChange); // now uninstall the watch
state.field1 = 101;
watch: test3.field1 changed from 99 to 100
watch: test3.field3 assigned value 'completely new'
watch: test3.field2 changed from 'hello' to 'Goodbye'
watch: test3.emptyArray assigned a new array [ ]
watch: test3.newArray assigned a new array ['one','two']
watch: test3.newArray.2 assigned value 'three'
watch: test3.newArray.length changed from 3 to 3
watch: test3.sub1 assigned a new object: {"sub1a":"value1a","sub1b":"value1b"}
watch: test3.sub1.sub1b changed from 'value1b' to 'new1b'