Upgrade to Pro — share decks privately, control downloads, hide ads and more …

State Management with Angular Signals - Inaugural Online Meetup 10/2023

State Management with Angular Signals - Inaugural Online Meetup 10/2023

ANGULARarchitects.io - Michael Egger-Zikes

Angular 16 introduced a new reactive primitive called Signals. Those APIs offer an additional concept beside RxJS to handle reactivity and influence the framework in many areas. Signals will lead to a different more fine-grained and more performant way of processing the Change Detection to update the view. All of this is added in a backwards compatible way.

State Management libraries like NgRx have used RxJS to handle reactivity, but they are currently introducing Signal APIs as well. By looking at State Management Selectors which directly return Signals or future Signal-based framework APIs for Form State, a new for-loop or Component-Inputs, we will use Signals in many areas of our frontend codebase.

This talk will give an overview how Signals can be used for managing local and global state and which other parts of the framework will be influenced by the new reactive API.

Michael Egger-Zikes

October 19, 2023
Tweet

More Decks by Michael Egger-Zikes

Other Decks in Programming

Transcript

  1. About Michael • Michael Egger-Zikes ANGULARarchitects.io • Focus on Angular

    • Trainings, Consultancy, Reviews • Conference Speaker Public: in-person or remote In-House: everywhere angulararchitects.io /en/angular-workshops Michael Egger-Zikes @MikeZks
  2. Reactive Primitive • Reactive Primitive • Return the current value

    synchronously • Same value does not trigger update • Can update consuming logic on change automatically • Signals & RxJS • No direct replacement for RxJS, though it may become optional • Allows subscription management for Observable Streams • Easier to use in Templates Michael Egger-Zikes (@MikeZks)
  3. Signal API – already State Management? • WritableSignal • Signal

    is a Function and Object combined • user = signal({ name: 'michael.egger-zikes' }) • <p>{{ user().name }}</p> • Update Signal value • Overwrite • user.set({ name: 'manfred.steyer' }) • Immutable • user.update(u => ({ ...u, name: 'manfred.steyer' })) • Mutable • user.mutate(u => { u.name = 'manfred.steyer'; }) Michael Egger-Zikes (@MikeZks)
  4. Derived State • Computed Signal • Uses Signals als Inputs

    to create derived state • userStr = computed(() => 'User: ' + user().name) • Side Effects • Is executed again, if consuming Signals change • effect(() => console.log(user(), product())) Michael Egger-Zikes (@MikeZks)
  5. Signals Interop w/ RxJS & NgRx Michael Egger-Zikes (@MikeZks) toObservable(signal)

    toSignal(observable$) takeUntilDestroyed() this.store.selectSignal(ngrxSelectorFn)
  6. Signal Store & Component • Custom Store Setup • export

    const CustomLocalStore = signalStore( withState<LocalState>(initialLocalState), withSignals(), withMethods() ); • providers: [CustomLocalStore] • localStore = inject(CustomLocalStore) Michael Egger-Zikes (@MikeZks)
  7. Signal Store Usage • Local UI State • For one

    Component only • Destroyed with Component • Component needs to manage complex state • Global State • Root-level Provider • App Lifetime • Can be used as lean alternative for the full Redux pattern Michael Egger-Zikes (@MikeZks)
  8. Signal Store Usage • Independent State • Component Provider •

    For a group of Features/Smart Components • Shared State • Component Provider • For a group of common Components/UI Components Michael Egger-Zikes (@MikeZks)
  9. API – Redux light • Updater → withMethods() • Similar

    to Actions & Reducer • Selectors → withSignals() • Custom Signals • Composition • Effects → withMethods() + rxMethod() • (Async) Side-Effects • T | Signal<T> | Observable<T> • Connect View Processing • Connect Global State Management • Trigger State Update Michael Egger-Zikes (@MikeZks)
  10. API – withMethod / rxMethod • Signal & Observable API

    (withMethod & rxMethod) • Pass in a Signal or a Stream • Automatic Subscription Management • triggerUserUpdate(userSignal) • triggerUserUpdate(userObservable$) • Non-Reactive API • Pass in Array, Object, string, number, … • Callable from Template • addUser({ id: 1, firstname: Sarah, lastname: Doe }) • triggerUserUpdate(user) Michael Egger-Zikes (@MikeZks)
  11. Complexity & Reactivity • Opinionated • Clear APIs, Clear Patterns

    • Similar to Redux, but more lightweight • Reduce overall complexity of Components • Smart Component focuses on the view rendering & user interaction • Local State Management processes the logical parts • Reactive, immutable State Management • Enhances Performance Michael Egger-Zikes (@MikeZks)
  12. Signal-based Components • APIs for automatic Signal creation • flight

    = input() • Computed Signal • selected = model() • Proxy Signal • @for (flight of bookingFeature.flights(); track flight.id) { } • Reactive @for provides Signals to trigger the Embedded Views • Important for future browser updates • Signal-based Change Detection w/o Zone.js or combined with Zone.js • Signal reads trigger a Change Detection processing only Michael Egger-Zikes (@MikeZks)
  13. [web] ANGULARarchitects.io [twitter] Michael Egger-Zikes (@MikeZks) [repo] https://github.com/mikezks/meetup-signals-state [repo] https://github.com/mikezks/signals-experimental

    Contact • Slides • Code Remote Workshops: Public & tailored to your company angulararchitects.io/angular-workshops