useScope
Create a context with owned effects and lifecycle cleanup.
Create a context with owned effects and lifecycle cleanup.
Overview
The useScope function allows you to create a scope for an app or composable, enabling you to manage initialization and cleanup tasks specific to that scope. Scopes are useful for organizing and encapsulating logic within your components.
Components are always created in scope using defineComponent function.
Try it live
Ready. Mount the ticker to start its interval.
Unmount the child: the tick count stops. Remount it: a fresh interval starts. The parent keeps the totals.
import { defineComponent, html, onMounted, onUnmounted, ref } from 'regor'
export function createLifecycle(interactive = false) {
const active = ref(false)
const toggle = () => active(!active())
const ticks = ref(0)
const starts = ref(0)
const cleanups = ref(0)
const lastEvent = ref('Ready. Mount the ticker to start its interval.')
const SessionTicker = defineComponent(
html`<p class="guide-ticker">
Interval running <span aria-hidden="true">●</span>
</p>`,
{
context: () => {
let timer: ReturnType<typeof setInterval> | undefined
onMounted(() => {
starts(starts() + 1)
lastEvent('onMounted → start interval')
timer = setInterval(() => ticks(ticks() + 1), 500)
})
onUnmounted(() => {
clearInterval(timer)
cleanups(cleanups() + 1)
lastEvent('onUnmounted → clear interval')
})
return {}
},
},
)
// No child is mounted during static rendering, so the build creates no timer.
return {
interactive,
active,
toggle,
ticks,
starts,
cleanups,
lastEvent,
components: { SessionTicker },
}
}
export const lifecycleTemplate = html` <div class="guide-demo">
<div class="guide-session-bar">
<button type="button" @click="toggle" :disabled="!interactive">
{{ active ? 'Unmount ticker' : 'Mount ticker' }}</button
><span>{{ active ? 'Child is mounted' : 'Child is unmounted' }}</span>
</div>
<SessionTicker r-if="active" />
<div class="guide-metrics">
<div><output>{{ ticks }}</output><span>Total ticks</span></div>
<div><output>{{ starts }}</output><span>Mounts</span></div>
<div><output>{{ cleanups }}</output><span>Cleanups</span></div>
</div>
<p class="guide-event" role="status">{{ lastEvent }}</p>
<p class="guide-hint">
Unmount the child: the tick count stops. Remount it: a fresh interval
starts. The parent keeps the totals.
</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)
} Mount the child ticker, then unmount it. The parent keeps totals while the child releases its interval.
Usage
Creating a Scope
To create a scope for an app or composable, call the useScope function and pass a context function as its argument. The context function is used to set up the scope's context and register initialization and cleanup tasks.
import { createApp, defineComponent, html, useScope, onUnmounted, ref, computed, watchEffect } from 'regor'
const userRow = defineComponent(html`<div></div>`, {
context: () => {
// Register an onUnmounted callback
onUnmounted(() => {
// Perform cleanup tasks
console.log('Component is unmounted!')
})
return {}
},
})
createApp(
useScope(() => {
// Register an onUnmounted callback
onUnmounted(() => {
// Perform cleanup tasks
console.log('App is unmounted!')
})
return {}
}),
)
const ref1 = ref(5)
const scope = useScope(() => {
watchEffect(() => {
// do some reactive tasks
})
const computedValue = computed(() => ref1() * 2)
return { computedValue }
})
scope.unmount() // Registered observers by watchEffect and computed are cleaned up Cleanup and Unmounting
Scopes are especially useful for defining cleanup behavior when a component is unmounted. You can register onUnmounted callbacks within the scope to handle cleanup tasks.
Parameters
context(required): A function that sets up the context and registers initialization and cleanup tasks for the scope.
Return Value
- An object containing the following properties:
context: The context of the scope that can be used within the component or composable.unmount: A function that, when called, triggers the cleanup tasks registered within the scope. It is automatically being called when the app or component is unmounted. It can be manually caled for custom scopes.
Use useScope around app setup. A component’s context factory already runs in a component scope.
Notes
-
Scopes help you encapsulate and organize component-specific logic, making it easier to manage initialization and cleanup tasks.
-
Multiple scopes can be created within a single component or composable to isolate different sets of tasks.