linkedSignal: управлять связанным состоянием теперь ещё проще
- пятница, 1 ноября 2024 г. в 00:00:07
Бу! Испугался? Не бойся. Angular 19 уже не за горами и представляет новый мощный примитив, называемый linkedSignal, который поможет вам управлять сложным состоянием в ваших приложениях. Это альтернатива использованию effect
для простого обновления сигнала на основе изменения другого сигнала. В сообществе не все были согласны (впрочем, как и всегда), некоторые продвигали идею использовать computed
вместо effect
для сброса сигналов на основе изменения другого сигнала.
linkedSignal
— это функция, призванная упростить этот процесс, она позволяет связывать сигналы, чтобы их значения автоматически синхронизировались на основе зависимости. Это полезно для создания реактивных данных, когда одно значение должно автоматически обновляться при изменении другого.
Допустим у нас есть сигнал, который представляет количество рублей на счёте пользователя:
const amountRubles = signal(700);
Теперь создадим сигнал, который автоматически будет пересчитывать наше значение в юани:
const amountYuan = linkedSignal(() => amountRubles() / 13.63);
amountRubles и amountYuan возвращают WritableSignal
, это расширенный интерфейс сигнала, который позволяет устанавливать/обновлять значения и делать их только для чтения.
Этот же код, но написанный через effect
:
const amountYuan = signal(amountRubles() / 13.63);
effect(() => {
amountYuan.set(amountRubles() / 13.63);
});
Результат при изменении основного сигнала такой же, связанный автоматически изменится:
console.log(amountRubles()); // 700
console.log(amountYuan()); // 51.35
amountRubles.set(1000);
console.log(amountRubles()); // 1000
console.log(amountYuan()); // 73.36
Существуют ситуации, когда нужна возможность задать более гибкие настройки. linkedSignal
позволяет передать объект, в котором будет прописана логика обновления:
selectedCity = signal('Москва');
weatherSignal = linkedSignal({
source: () => this.selectedCity(), // Базовый сигнал (источник)
computation: (city, previous) => {
if (previous?.source === city && previous?.value) {
// Если город не изменился, используем предыдущее значение
return previous.value;
}
// Получение прогноза из API при изменении города
return this.fetchWeather(city);
},
equal: (newVal, oldVal) => newVal.temperature === oldVal.temperature
// equal предотвращает лишние обновления, если температура осталась прежней
});
Этот подход позволяет создать linkedSignal
, который автоматически обновляется, только если изменяется температура для выбранного города, что минимизирует ненужные перерисовки.
Автоматическая синхронизация данных
При изменении одного состояния, все связанные с ним данные обновляются автоматически. Это позволяет избежать «ручных» пересчётов и синхронизации, что снижает вероятность ошибок
Реактивность без дополнительных зависимостейlinkedSignal
делает код более прямолинейным, так как позволяет работать с реактивными данными без традиционного RxJS
Упрощение логики и повышение читаемости
Использование linkedSignal
снижает количество кода для обработки реактивности. Когда зависимости декларативно указаны в функции linkedSignal
, код становится чище и легче в поддержке, так как видно, какие именно значения влияют на связанный сигнал
Повышение производительностиlinkedSignal
оптимизирует вычисления, вызывая пересчёт только в тех местах, где действительно изменилось состояние. Это снижает нагрузку на приложение по сравнению с неэффективными пересчётами