Untracked — это механизм Solid.js, позволяющий выполнять функцию без создания реактивных зависимостей. Он необходим в ситуациях, когда требуется избежать автоматического подписывания на сигналы, чтобы предотвратить ненужные перерендеры и повысить производительность.
В Solid.js реактивность строится вокруг сигналов
(createSignal) и эффектов
(createEffect). Обычно при чтении сигнала внутри эффекта
автоматически создаётся зависимость, и эффект будет повторно вызываться
при изменении сигнала. Иногда требуется выполнить код, который читает
сигналы, но не должен становиться зависимым от их изменений. Для этого
используется untrack.
import { createSignal, untrack } from "solid-js";
const [count, setCount] = createSignal(0);
const value = untrack(() => count()); // Чтение без подписки
В этом примере value получит текущее значение
count, но не будет автоматически обновляться при
последующих изменениях сигнала.
import { createSignal, createEffect, untrack } from "solid-js";
const [count, setCount] = createSignal(0);
const [trigger, setTrigger] = createSignal(false);
createEffect(() => {
console.log("Effect triggered by trigger:", trigger());
const currentCount = untrack(() => count());
console.log("Current count (untracked):", currentCount);
});
setCount(1); // Не вызовет эффект
setTrigger(true); // Вызовет эффект
Здесь count читается без создания зависимости, поэтому
изменение его значения не перезапускает эффект.
createMemo) Иногда нужно создать вычисление,
которое частично зависит от сигналов, но некоторые данные должны быть
получены без подписки:import { createSignal, createMemo, untrack } from "solid-js";
const [a, setA] = createSignal(1);
const [b, setB] = createSignal(2);
const memo = createMemo(() => {
const untrackedB = untrack(() => b());
return a() + untrackedB;
});
console.log(memo()); // 3
setB(5);
console.log(memo()); // 3, не изменилось
setA(3);
console.log(memo()); // 8, обновилось только по изменению a
untrack позволяет выборочно отключить реактивность для
определённых сигналов, оставляя остальные зависимости активными.
Без untrack любое чтение сигнала внутри реактивного
контекста создаёт зависимость. Это полезно для автоматического
обновления интерфейса, но иногда приводит к лишним ререндерингам.
untrack даёт точечный контроль:
untrack работает, временно отключая текущий
реактивный контекст. Solid.js хранит стек эффектов, и
untrack выполняет функцию в контексте, где стек очистлен,
поэтому чтение сигналов не создаёт подписок. После выполнения стек
восстанавливается, и последующие чтения снова становятся
реактивными.
function untrack(fn) {
const prev = getListener(); // Сохраняем текущий эффект
setListener(null); // Отключаем реактивный контекст
try {
return fn();
} finally {
setListener(prev); // Восстанавливаем эффект
}
}
untrack — инструмент тонкой настройки реактивности. Он
позволяет избежать лишних перерендеров, сохраняя высокую скорость и
детерминированность работы приложений Solid.js.