signal
The core reactive primitive. A signal is an object that holds a value and notifies any interested consumers when that value changes.
// Create a signal with an initial valuefunction signal<T>(initialValue: T): Signal<T>
// Create a signal with an initial value of `undefined`function signal<T>(): Signal<T | undefined>
// A signal is a function that acts as both a getter and a setterinterface Signal<T> { (): T; // Get the current value (value: T): void; // Set a new value}
TypeScript Integration
Section titled “TypeScript Integration”TypeScript provides excellent type safety for signals. The type is inferred from the initial value, but can also be set explicitly.
// Inferred as Signal<number>const count = signal(0);
// Inferred as Signal<string>const name = signal("Hella");
// Explicitly typed signaltype Status = 'loading' | 'success' | 'error';const status = signal<Status>('loading');
Basic Usage
Section titled “Basic Usage”To read a signal’s value, call it with no arguments. To update it, call it with the new value.
import { signal } from '@hellajs/core';
// Create a signalconst count = signal(0);
// Read the valueconsole.log(count()); // 0
// Set a new valuecount(10);console.log(count()); // 10
// Signals can hold any data typeconst user = signal({ name: "John" });const tags = signal(["a", "b"]);
Reactivity
Section titled “Reactivity”Signals are the foundation of the reactive system. When a signal is read inside a computed
or effect
, a dependency is created. When the signal’s value changes, the computation will automatically update.
import { signal, computed, effect } from '@hellajs/core';
const firstName = signal("John");const lastName = signal("Doe");
// `computed` depends on `firstName` and `lastName`const fullName = computed(() => `${firstName()} ${lastName()}`);
// `effect` depends on `fullName`effect(() => { console.log(`Welcome, ${fullName()}!`);});// Logs: "Welcome, John Doe!"
firstName("Jane");// Logs: "Welcome, Jane Doe!"
Working with Objects and Arrays
Section titled “Working with Objects and Arrays”Signals detect changes using strict equality (===
). When working with objects or arrays, you must pass a new object or array to trigger an update. Modifying the existing object in place will not work.
const user = signal({ name: 'John', age: 30 });
// ❌ Incorrect: This mutates the object but doesn't trigger an update// because the object reference is the same.user().age = 31;user(user()); // Nothing happens
// ✅ Correct: Create a new objectuser({ ...user(), age: 31 });
const items = signal(['a', 'b']);
// ❌ Incorrect: `push` mutates the array in place.items().push('c');items(items()); // Nothing happens
// ✅ Correct: Create a new arrayitems([...items(), 'c']);
For managing complex state, consider using multiple signals for independent properties or exploring the @hellajs/store
package.