What is one of the harder things, if not the hardest, you have ever done in an Angular project?

State

State

Angular State Management - Start Local

@devupconf - STL 2022

Chau Tran

twitter.com/@nartc1410

github.com/nartc

and all the Sponsors (https://www.devupconf.org/sponsors)

and all the Sponsors (https://www.devupconf.org/sponsors)

When should we use state management?

– Any Angular developer ever

There should be 3 answers here

Never

Never

Never

Never

When needed or "it depends"

Never

Never

When needed or "it depends"

Always

Never

Never

When needed or "it depends"

Always

Subject as a Service

Never

Never

When needed or "it depends"

Always

Never

Never

When needed or "it depends"

Always

Never

Never

When needed or "it depends"

Always

and more.

(who doesn't like to own a State Management library)

Common?

Global State Management

What is State Management?

What is State Management?

FeatureA

FeatureB

FeatureC

StateA

StateB

StateC

App

FeatureA

FeatureB

FeatureC

StateA

StateB

StateC

App

FeatureA

FeatureB

FeatureC

StateA

StateB

StateC

App

FeatureA

FeatureB

FeatureC

StateA

StateB

StateC

App

Primer on

Local Component State

Primer on

Local Component State

Primer on

Local Component State

Anything that contributes to rendering a component

Primer on

Local Component State

Anything that contributes to rendering a component

Persisted State

Primer on

Local Component State

Anything that contributes to rendering a component

Persisted State

URL State

Primer on

Local Component State

Anything that contributes to rendering a component

Persisted State

URL State

Client State

Primer on

Local Component State

Anything that contributes to rendering a component

Persisted State

URL State

Client State

Local UI State

Primer on

Local Component State

Anything that contributes to rendering a component

Persisted State

URL State

Client State

Local UI State

Primer on

Local Component State

Anything that contributes to rendering a component

Persisted State

URL State

Client State

Local UI State

What do we even want from a State Management solution?

In my opinion, a State Management solution should provide

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
}

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable({ providedIn: 'root' })
export class StateService {
    private state$ = new ReplaySubject(1);
}

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
}

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
  
    select(selector) {
        return this.state$.pipe(
            map(state => selector(state)),
            distinctUntilChanged()
        )
    }
}

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
  
    select(selector) {
        return this.state$.pipe(
            map(state => selector(state)),
            distinctUntilChanged()
        )
    }
  
    setState(state) {
        if (typeof state === 'function') {
            this.state$.next(state(this.state$.getValue()));
        } else {
            this.state$.next(state);
        }
    }
  
    patchState(partialState) {
        const currentState = this.state$.getValue();
        if (typeof partialState === 'function') {
            this.state$.next({
                ...currentState,
                ...partialState(currentState)
            });
        } else {
            this.state$.next({
                ...currentState,
                ...partialState
            })
        }
    }
}

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
  
    select(selector) {
        return this.state$.pipe(
            map(state => selector(state)),
            distinctUntilChanged()
        )
    }
  
    setState(state) {
        // ...
    }
  
    patchState(partialState) {
        // ...
    }
  
    effect(trigger) {
        return trigger.subscribe();
    }
}

In my opinion, a State Management solution should provide

- Ability to read states with some diffing mechanism

- Ability to write to states fully or partially

- Ability to handle side-effects

- Ease of clean up

@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
    private destroy$ = new ReplaySubject(1);
  
    select(selector) {
        return this.state$.pipe(
            map(state => selector(state)),
            distinctUntilChanged()
        )
    }
  
    setState(state) {
        // ...
    }
  
    patchState(partialState) {
        // ...
    }
  
    effect(trigger) {
        return trigger
          .pipe(takeUntil(this.destroy$))
          .subscribe();
    }
  
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
}
@Injectable()
export class StateService {
    private state$ = new ReplaySubject(1);
    private destroy$ = new ReplaySubject(1);
  
    select(selector) {
        return this.state$.pipe(
            map(state => selector(state)),
            distinctUntilChanged()
        )
    }
  
    setState(state) {
        // ...
    }
  
    patchState(partialState) {
        // ...
    }
  
    effect(trigger) {
        return trigger
          .pipe(takeUntil(this.destroy$))
          .subscribe();
    }
  
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
}

Congratulations!

You just implemented

@ngrx/component-store

Pull-based state management

@ngrx/component-store

@ngrx/component-store

@ngrx/component-store

Read

Write

Side-effect

@ngrx/component-store

Read

Write

Side-effect

@ngrx/store

@ngrx/component-store

Read

Write

Side-effect

@ngrx/store

createSelector()

createReducer()

createEffect()

@ngrx/component-store

Read

Write

Side-effect

@ngrx/store

createSelector()

createReducer()

createEffect()

@ngrx/component-store

select()

setState()

effect()

Demo

Credits

Laura - https://twitter.com/ltciro

Diana - https://twitter.com/dicaro87

Thank you

Made with Slides.com