LogoSignals.dart
Copy Markdown
rodydavis/signals.dart 999999

Computed

Represents a derived, read-only reactive state value computed from one or more other signals.

Represents a derived, read-only reactive state value computed from one or more other signals.

Computed signals are lazily evaluated and memoized (cached). Their callback function fn is only executed when its value is read and one of its upstream dependencies has mutated since the last calculation. If none of the dependencies have changed, the cached value is returned directly.

Under the hood, a Computed signal tracks its sources dynamically. If a conditional branch inside the computation changes such that certain signals are no longer read, those signals are automatically pruned from the dependency list, preventing redundant triggers.

The computation callback **fn** should be **pure** and side-effect free. Writing to other signals or performing network/database operations inside a computed callback is a critical anti-pattern that can lead to infinite loops (cycles) or unpredictable state transitions.

Example Usage#

1. Basic Derived State

import 'package:preact_signals/preact_signals.dart';

void main() {
  final firstName = Signal('Jane');
  final lastName = Signal('Doe');

  // Computed automatically tracks both firstName and lastName
  final fullName = Computed(() => '${firstName.value} ${lastName.value}');

  print(fullName.value); // Jane Doe
  lastName.value = 'Smith';
  print(fullName.value); // Jane Smith
}

2. Dynamic Dependency Tracking (Branching)

final showFull = Signal(false);
final detailedInfo = Signal('High Latency Alert');
final briefInfo = Signal('Alert');

final message = Computed(() {
  if (showFull.value) {
    return detailedInfo.value; // Subscribes to detailedInfo
  } else {
    return briefInfo.value; // Subscribes to briefInfo
  }
});

Constructors#

View Constructors
Computed(this.fn, {String? name, void Function()? watched, void Function()? unwatched, ComputedOptions<T>? options})

Creates a new Computed signal instance with the derivation callback fn.

You can optionally provide:

  • A name for debugging/observer tracing.
  • watched/unwatched hooks triggered when the computed gains its first subscriber or loses its last subscriber.
final doubleCount = Computed(() => count.value * 2, name: 'double_counter');

Properties#

View Properties
T Function() fn

@internal The computation callback function.

int globalId
String? name
void Function()? watched
void Function()? unwatched
int internalGlobalVersion

@internal The internal global version of the computed signal.

int flags
SignalEffectException? error

@internal The captured exception from the latest computation run, if any.

int version

Methods#

View Methods
bool isInitialized

Check if the value has been computed

T internalValue
internalValue(T value)

@internal Set the internal value.

bool internalRefresh()
void subscribeToNode(Node node)
void unsubscribeFromNode(Node node)
void notify()
T value
void Function() subscribe(void Function(T value) fn)

computed#

Convenient global constructor for creating a derived computed signal.

Computed signals are lazily evaluated and cached (memoized). Their values automatically update when any dependency signals accessed inside the callback function change.

Example Usage#

import 'package:preact_signals/preact_signals.dart';

final firstName = signal('Jane');
final lastName = signal('Doe');

final fullName = computed(() => '${firstName.value} ${lastName.value}');

void main() {
  print(fullName.value); // Prints: Jane Doe
}