linkedSignal: управлять связанным состоянием теперь ещё проще

71e582ebc85fbfab74b51491c712f856.png

Бу! Испугался? Не бойся. 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 оптимизирует вычисления, вызывая пересчёт только в тех местах, где действительно изменилось состояние. Это снижает нагрузку на приложение по сравнению с неэффективными пересчётами

© Habrahabr.ru