Производные значения (derived values) — это механизм
для вычисления новых состояний на основе существующих реактивных данных.
В Atomico они позволяют формировать значения, которые автоматически
обновляются при изменении исходных сигналов (signals),
обеспечивая синхронизацию состояния без явного ручного контроля.
Производные значения создаются с помощью функции
computed. Она принимает один или несколько сигналов и
функцию вычисления нового значения. Сигналы могут быть как атомарными
(signal), так и другими производными значениями.
import { signal, computed } from "atomico";
const count = signal(0);
const doubleCount = computed(() => count.value * 2);
console.log(doubleCount.value); // 0
count.value = 3;
console.log(doubleCount.value); // 6
Ключевые моменты:
computed автоматически подписывается на все сигналы,
использованные внутри функции вычисления..value.Atomico использует ленивые вычисления. Производное значение
пересчитывается только при обращении к
.value, и только если хотя бы один из
сигналов изменился. Это позволяет минимизировать ненужные
пересчёты и повышает производительность в сложных компонентах.
const a = signal(2);
const b = signal(3);
const sum = computed(() => {
console.log("Пересчёт sum");
return a.value + b.value;
});
console.log(sum.value); // Пересчёт sum -> 5
console.log(sum.value); // 5, пересчёт не происходит
a.value = 4;
console.log(sum.value); // Пересчёт sum -> 7
computed может использовать сразу несколько сигналов.
При этом любое изменение хотя бы одного из сигналов инициирует
пересчёт.
const firstName = signal("Иван");
const lastName = signal("Петров");
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
console.log(fullName.value); // Иван Петров
firstName.value = "Алексей";
console.log(fullName.value); // Алексей Петров
В Atomico производные значения часто используются для связывания состояния с шаблоном компонента. Они позволяют сократить количество вручную управляемых эффектов и подписок.
import { c, useHost, html, css, signal, computed } from "atomico";
function Counter() {
const host = useHost();
const count = signal(0);
const doubled = computed(() => count.value * 2);
return html`
<div>
<p>Count: ${count.value}</p>
<p>Doubled: ${doubled.value}</p>
<button oncl ick=${() => count.value++}>Increment</button>
</div>
`;
}
Counter.styles = css`
p {
font-weight: bold;
}
`;
Особенности использования в компонентах:
.value.Производные значения могут быть вложенными, образуя цепочку зависимостей. Изменение сигнала в начале цепочки автоматически обновит все зависимые значения.
const base = signal(2);
const squared = computed(() => base.value ** 2);
const squaredPlusOne = computed(() => squared.value + 1);
console.log(squaredPlusOne.value); // 5
base.value = 3;
console.log(squaredPlusOne.value); // 10
Преимущества цепочек:
Сигналы (signal) хранят и изменяют состояние.
Производные значения (computed) не хранят состояние
напрямую, они вычисляются на основе других сигналов.
Разделение этих понятий улучшает структуру приложения:
Сигнал (signal) |
Производное значение (computed) |
|---|---|
| Хранит текущее состояние | Вычисляет состояние на основе сигналов |
| Изменяется напрямую | Не изменяется напрямую, зависит от сигналов |
| Может быть подписан на эффекты | Автоматически подписан на используемые сигналы |
Использование производных значений снижает количество ручных подписок и эффектов. При правильной организации вычислений:
В сложных компонентах рекомендуется создавать отдельные производные значения для каждой логической части состояния, вместо объединения всего в одном вычислении.
effectПроизводные значения можно использовать внутри effect
для реагирования на изменения состояния:
import { effect } from "atomico";
effect(() => {
console.log(`Сумма: ${sum.value}`);
});
effect будет автоматически отслеживать все сигналы и
производные значения, использованные внутри функции, обеспечивая
реактивное обновление.
Производные значения в Atomico формируют основу реактивного управления состоянием. Они обеспечивают чистую, предсказуемую и эффективную логику обновления компонентов, позволяя создавать сложные интерфейсы без лишнего кода.