signal
Метод signal позволяет создавать реактивные переменные, которые автоматически обновляют подписанные на них зависимости при изменении значения.
Обзор
Метод signal является фундаментальной частью реактивной системы, позволяя автоматически обновлять UI и другие зависимости при изменениях значений. Он поддерживает назначение начального значения, выполнение пользовательской валидации, логирование транзакций, группирование обновлений через engine.batch() и отслеживание зависимостей.
Синтаксис
engine.signal(initialValue, optionsOrName)Параметры
- initialValue (
T): Начальное значение сигнала. - optionsOrName (
string | SignalOptions<T>): Имя или опции сигнала.
Возвращаемое значение
Метод возвращает объект Signal, который имеет следующие свойства и методы:
value: Значение сигнала.subscribe(cb: (val: T) => void): Подписка на изменение значения сигнала. Возвращает функцию для очистки подписки.
Примеры
Пример на чистом TypeScript (Базовый)
const engine = new ReactiveEngineCore();
const count = engine.signal(0, { name: 'counter' });
count.subscribe((newValue) => {
console.log(`Count is now ${newValue}`);
});
count.value++; // Выведет: Count is now 1Пример на чистом TypeScript (Продвинутый с валидацией)
interface User { id: number; name: string; }
const engine = new ReactiveEngineCore();
const userSignal = engine.signal<User>({ id: 1, name: 'John Doe' }, {
name: 'user',
validate: (user) => user.id > 0 && typeof user.name === 'string'
});
userSignal.value = { id: -1, name: 'Jane Doe' }; // Ошибка валидацииПример на чистом TypeScript (Интеграция с React через DI контейнер)
interface User { id: number; name: string; }
class UserService {
constructor(engine: ReactiveEngineCore) {
this.mySignal = engine.signal<User>({ id: 1, name: 'John Doe' }, { name: 'userSignal' });
}
mySignal: Signal<User>;
}
const engine = new ReactiveEngineCore();
engine.provide(UserService, UserService);
const logic = engine.inject(UserService);
function MyComponent() {
const user = useReactiveValue(logic.mySignal);
return <div>{user.name}</div>;
}Дополнительная информация
Назначение начального значения
При создании сигнала с помощью метода signal, переданное начальное значение будет установлено в качестве текущего значения сигнала. Если значение изменяется, подписанные на него зависимости будут автоматически обновлены.
const engine = new ReactiveEngineCore();
const count = engine.signal(0);
console.log(count.value); // Выведет: 0
count.value = 1;
console.log(count.value); // Выведет: 1Выполнение пользовательской валидации значений
Метод signal поддерживает опциональную пользовательскую функцию валидации, которая может проверять и блокировать установку некорректных значений.
interface User { id: number; name: string; }
const engine = new ReactiveEngineCore();
const userSignal = engine.signal<User>({ id: 1, name: 'John Doe' }, {
name: 'user',
validate: (user) => user.id > 0 && typeof user.name === 'string'
});
userSignal.value = { id: -1, name: 'Jane Doe' }; // Ошибка валидации
console.log(userSignal.value); // Выведет: { id: 1, name: 'John Doe' }Логирование транзакций
Метод signal автоматически регистрирует изменения значений в системе логирования реактивных операций. Это позволяет отслеживать и отладить поведение системы.
const engine = new ReactiveEngineCore();
const count = engine.signal(0, { name: 'counter' });
count.subscribe((newValue) => {
console.log(`Count is now ${newValue}`);
});
count.value++; // Выведет: Count is now 1Группировка обновлений через engine.batch() (old)
Метод batch позволяет группировать несколько изменений значений в одну транзакцию, что повышает производительность и предотвращает излишние обновления зависимостей.
const engine = new ReactiveEngineCore();
const count1 = engine.signal(0);
const count2 = engine.signal(0);
engine.batch(() => {
count1.value++;
count2.value++;
});
console.log(`${count1.value}, ${count2.value}`); // Выведет: "1, 1"Пример с автобатчингом обновлений
const count1 = engine.signal(0, 'one');
const count2 = engine.signal(0, 'two');
count1.value++;
count2.value++;
console.log(`${count1.value}, ${count2.value}`); // Выведет: "1, 1"Отслеживание зависимостей
Сигналы автоматически отслеживают зависимости, которые зависят от их значений. Это позволяет эффективно обновлять только те части системы, которые действительно изменились.
const engine = new ReactiveEngineCore();
const count = engine.signal(0);
let doubledCount = 0;
engine.effect(() => {
doubledCount = count.value * 2;
});
console.log(doubledCount); // Выведет: 0
count.value++;
console.log(doubledCount); // Выведет: 2Эти примеры и объяснения демонстрируют основные возможности и особенности метода signal в реактивной системе.