observe
Subscribe to one ref and stop the subscription with the returned function.
Subscribe to one ref and stop the subscription with the returned function.
Overview
The observe function allows you to create observers that react to changes in ref objects, providing a callback that triggers when the ref's value changes. This is useful for handling side effects or updating UI elements based on reactive data.
Try it live
Source values: 0 / 0
After stopping, source values still change but the callback counts stay put.
import { html, observe, observeMany, observerCount, ref } from 'regor'
export function createObservation(interactive = false) {
const left = ref(0),
right = ref(0)
const single = ref(0),
multiple = ref(0),
listening = ref(true)
const count = ref(0)
const stopSingle = observe(left, () => single(single() + 1))
const stopMany = observeMany([left, right], () => multiple(multiple() + 1))
// These source refs are not rendered directly, so this count isolates our observers.
const refresh = () => count(observerCount(left))
const values = ref('0 / 0')
const bumpLeft = () => {
left(left() + 1)
values(`${left()} / ${right()}`)
refresh()
}
const bumpRight = () => {
right(right() + 1)
values(`${left()} / ${right()}`)
refresh()
}
const stop = () => {
stopSingle()
stopMany()
listening(false)
refresh()
}
refresh()
return {
interactive,
values,
single,
multiple,
listening,
count,
bumpLeft,
bumpRight,
stop,
}
}
export const observationTemplate = html` <div class="guide-demo">
<div class="guide-session-bar">
<button type="button" @click="bumpLeft" :disabled="!interactive">
Update left</button
><button type="button" @click="bumpRight" :disabled="!interactive">
Update right</button
><button type="button" @click="stop" :disabled="!interactive || !listening">
Stop observers
</button>
</div>
<p>Source values: <strong>{{ values }}</strong></p>
<div class="guide-metrics">
<div>
<output>{{ single }}</output><span>observe · left callbacks</span>
</div>
<div>
<output>{{ multiple }}</output><span>observeMany · callbacks</span>
</div>
<div><output>{{ count }}</output><span>Observers on left</span></div>
</div>
<p class="guide-hint">
After stopping, source values still change but the callback counts stay put.
</p>
</div>` import { createApp, RegorConfig, useScope } from 'regor'
import { apiExamples } from './examples'
const element = document.getElementById('api-demo')
const name = element?.dataset.example
if (element && name && Object.hasOwn(apiExamples, name)) {
const example = apiExamples[name as keyof typeof apiExamples]
const scope = useScope<object>(() => example.create(true))
const config =
'config' in scope.context && scope.context.config instanceof RegorConfig
? scope.context.config
: undefined
createApp(scope, { element, template: example.template }, config)
} Update either source, then stop the observers. Their callback counts stop while source values keep changing.
Usage
Creating Observers
To create an observer, you can use the observe function, passing in a ref object and a callback function.
import { observe, ref } from 'regor'
const myRef = ref('Hello, Regor!')
// Create an observer
const stopObserving = observe(myRef, (newValue) => {
console.log('Value changed:', newValue)
}) Parameters
source: The ref object you want to observe for changes.observer: A callback function that will be triggered whenever the ref's value changes.init(optional): Iftrue, the observer will be immediately invoked with the current value of the ref when it's created.
Return Value
- The
observefunction returns astopObservingfunction that allows you to stop the observer when it's no longer needed. CallingstopObservingwill unsubscribe the observer from the ref object.
Example
import { observe, ref } from 'regor'
const myRef = ref('Hello, Regor!')
// Create an observer with init set to true
const stopObserving = observe(
myRef,
(newValue) => {
console.log('Value changed:', newValue)
},
true,
)
// Later, when the observer is no longer needed, stop it
stopObserving() Keep the returned stop function for explicit teardown. Scoped observers are also associated with their owner’s cleanup.