untrack
Ejecuta una función que lee señales sin registrarlas como dependencias del observador activo.
Se autoimporta en las aplicaciones del framework.
import { untrack } from "@meekojs/meeko";Dentro de un effect, un computed o la plantilla, leer signal.value suscribe al observador: cuando la señal cambie, se volverá a ejecutar. untrack(fn) ejecuta fn sin observador activo, así que las señales que lee dentro no se registran. Sirve para leer un valor de contexto (el usuario, la página actual, una opción) sin que su cambio dispare el trabajo.
Se exporta desde @meekojs/meeko y se autoimporta en las aplicaciones del framework.
Uso#
import { effect, signal, untrack } from "@meekojs/meeko";
const query = signal("");
const page = signal(1);
// Se repite al cambiar query; page se lee sin suscribirse.
effect(() => {
console.log(`Buscar "${query.value}" desde la página ${untrack(() => page.value)}`);
});
page.value = 2; // sin log
query.value = "a"; // log: Buscar "a" desde la página 2Tipo#
function untrack<T>(fn: () => T): TParámetros#
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
fn |
() => T |
obligatorio | Función que lee señales. Se ejecuta en el momento, una vez. |
Valor devuelto#
Lo que devuelve fn. Fuera de un observador, untrack(fn) equivale a llamar a fn().
Ejemplos#
Registrar un evento con un dato que no debe repetirlo#
import { effect, signal, untrack } from "@meekojs/meeko";
const route = signal("/");
const userId = signal("anon");
effect(() => {
const path = route.value; // la dependencia
void fetch("/api/analytics", {
method: "POST",
body: JSON.stringify({ path, user: untrack(() => userId.value) }),
});
});Cambiar de usuario no envía una visita nueva; cambiar de ruta sí.
Un valor inicial que no debe seguir a la prop#
En un computed, untrack fija lo que no debe recalcularlo:
<!-- app/components/Draft.meeko -->
<script lang="ts">
const props = defineProps<{ text: string; locale: string }>();
const draft = signal(untrack(() => props.text)); // copia inicial, a propósito
const words = computed(() => draft.value.trim().split(/\s+/).filter(Boolean).length);
</script>
<template>
<textarea model="draft"></textarea>
<p>{words.value} palabras</p>
</template>props.text sólo se lee una vez; el usuario edita la copia en draft.
Llamar a código ajeno desde un efecto#
Una función de una librería puede leer señales que no controlas. untrack evita que el efecto dependa de ellas:
import { effect, signal, untrack } from "@meekojs/meeko";
declare function notify(message: string): void; // puede leer señales internas
const saved = signal(0);
effect(() => {
if (saved.value > 0) untrack(() => notify(`Guardado ${saved.value}`));
});Errores comunes#
Devolver la señal en lugar de su valor#
untrack sólo evita la suscripción mientras fn se ejecuta. Si devuelve la señal, la lectura ocurre después, fuera de untrack, y sí se registra.
effect(() => {
const current = untrack(() => page);
console.log(query.value, current.value); // page vuelve a ser dependencia
});No hay error: el efecto se repite al cambiar page. Lee .value dentro de la función:
effect(() => {
console.log(query.value, untrack(() => page.value));
});Usarlo para tapar un bucle#
Si un efecto escribe una señal que también lee, untrack en la lectura evita el error Reactive update cycle exceeded 1000 iterations, pero deja un estado que se deriva a mano.
effect(() => {
total.value = untrack(() => total.value) + price.value;
});total acumula cada cambio de price y no vuelve atrás nunca. Si el valor depende de otros, es un computed:
const total = computed(() => items.value.reduce((sum, item) => sum + item.price, 0));Notas#
- Servidor y navegador. Funciona igual en los dos.
- Escrituras.
untrackno cambia las escrituras: una asignación dentro defnavisa a los observadores como siempre. Para agruparlas, usabatch. - Callbacks de Meeko.
onMountedy las funciones que Meeko ejecuta tras la hidratación ya corren sin seguimiento: no hace faltauntrackdentro. - Plantilla. En una expresión de la plantilla,
untrackhace que ese binding no se actualice cuando cambia la señal. Es raro necesitarlo; normalmente indica que el dato debería ser una constante.