entangle
Link two writable refs in both directions and return a function to disconnect them.
Link two writable refs in both directions and return a function to disconnect them.
Overview
The entangle function allows you to create a bidirectional link between two refs, ensuring that changes in one ref are mirrored in the other. This bidirectional linking is particularly useful when you want two refs to always have the same value.
Try it live
Edit either side. Disconnect the link, then edit again.
import { entangle, html, ref } from 'regor'
export function createEntanglement(interactive = false) {
const left = ref('Shared title'),
right = ref('')
const linked = ref(true)
const stop = entangle(left, right)
return {
interactive,
left,
right,
linked,
disconnect: () => {
stop()
linked(false)
},
}
}
export const entanglementTemplate = html` <div class="guide-demo">
<div class="guide-filter">
<label
>Left ref<input
type="text"
maxlength="50"
r-model="left"
:value="left"
:disabled="!interactive" /></label
><label
>Right ref<input
type="text"
maxlength="50"
r-model="right"
:value="right"
:disabled="!interactive"
/></label>
</div>
<div class="guide-session-bar api-actions">
<button
type="button"
@click="disconnect"
:disabled="!interactive || !linked"
>
Disconnect the refs</button
><span>{{ linked ? 'Two-way link active' : 'Refs are independent' }}</span>
</div>
<p class="guide-hint">
Edit either side. Disconnect the link, then edit again.
</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)
} Edit either side while the link is active. Disconnect it to make the refs independent.
Usage
Creating a Bidirectional Link
To create a bidirectional link between two refs, simply call the entangle function with the two refs as arguments. After calling entangle, any changes made to one ref will be automatically reflected in the other.
import { entangle, ref } from 'regor'
const ref1 = ref(5)
const ref2 = ref(10)
const stopEntangle = entangle(ref1, ref2)
console.log(ref1.value) // Outputs: 5
console.log(ref2.value) // Outputs: 5
ref1.value = 15 // Both refs are updated
console.log(ref1.value) // Outputs: 15
console.log(ref2.value) // Outputs: 15
stopEntangle() // Stop the bidirectional linking Parameters
r1: The first ref that you want to entangle.r2: The second ref that you want to entangle.
Return Value
- The
entanglefunction returns a function that, when called, stops the bidirectional linking between the two refs.
Keep the returned stop function when a two-way link should end before its owner unmounts.
Notes
-
Changes made to either of the entangled refs will be automatically reflected in the other, ensuring that they always have the same value.
-
It's important to call the returned function to stop the bidirectional linking when you no longer need it to prevent unintended updates.
-
Circular entanglements, where ref1 and ref2 form a circular dependency, should be avoided, as they can lead to infinite loops and unpredictable behavior.
Example
import { entangle, ref } from 'regor'
const ref1 = ref(5)
const ref2 = ref(10)
const stopEntangle = entangle(ref1, ref2)
console.log(ref1.value) // Outputs: 5
console.log(ref2.value) // Outputs: 5
ref1.value = 15 // Both refs are updated
console.log(ref1.value) // Outputs: 15
console.log(ref2.value) // Outputs: 15
stopEntangle() // Stop the bidirectional linking