# Thinking in Signals

## Hi, I'm Tomasz

Independent Consultant & Software Architect

Trainer, Speaker, JS/TS Expert

ArchitekturaNaFroncie.pl (ANF)

Warsaw, PL

tomasz (at) ducin.dev

@tomasz_ducin

let rate = 3.94;
let amount = 1000;
let exchange = amount / rate; // 253.80

rate = 3.97;
exchange // OUT OF SYNC!

# invariant

a condition which is true BEFORE and AFTER a change

# REACTIVE w/RxJS

let rate\$ = new BehaviorSubject(3.94);
let amount\$ = new BehaviorSubject(1000);
let exchange\$ = combineLatest(
amount\$, rate\$,
(amount, rate) => amount / rate
);
rate\$.next(3.97) // exchange -> 251.89

# REACTIVE w/signals

let rate = signal(3.94);
let amount = signal(1000);
let exchange = computed(
() => amount() / rate()); // 253.80
rate.set(3.97) // exchange() == 251.89

# Local State

@Component({...})
class MyComponent {
private rate = signal(...)
private amount = signal(...)
public exchange = computed(...)
}

# Shared State

@Injectable({...})
class MyService {
private rate = signal(...)
private amount = signal(...)
public exchange = computed(...)
}
@Component({...})
class MyComponent {
constructor(
private myService: MyService
){}
}

# Signal State Class (VM)

class MySignalState {
private rate = signal(...)
private amount = signal(...)
public exchange = computed(...)
}
@Component({...})
class MyComponent {
state = new MySignalState()
}
@Injectable({...})
class MyService {
state = new MySignalState()
}

# Signal State Machine

| { type: "DATA_LOADED", items: Entity[] }
| { type: "ERROR", error: Error }

class MySignalState {

}
<div>
<app-entity-list [items]="state.items" />
} @else if (state.type == "ERROR") {
<app-error-messsage [message]="state.error.message" />
} @else ...
</div>
sig = signal(t) // WritableSignal<T>

sig.set(t)
sig.update(oldT => newT)

c = computed(() => sig())
e = effect(() => display(sig()))

// NO SUBSCRIBE, NO UNSUBSCRIBE

# Static data

let rate = 3.94;
let amount = 1000;
let exchange = amount / rate; // 253.80

rate = 3.97;
exchange // OUT OF SYNC!

# Reactive Streams

let rate\$ = new BehaviorSubject(3.94);
let amount\$ = new BehaviorSubject(1000);
let exchange\$ = combineLatest(
amount\$, rate\$,
(amount, rate) => amount / rate
);
rate\$.next(3.97) // exchange -> 251.89

# Signals

## performance (fine-grained CD)

let rate = signal(3.94);
let amount = signal(1000);
let exchange = computed(
() => amount() / rate()); // 253.80
rate.set(3.97) // exchange() == 251.89

By Tomasz Ducin

• 269