Angular Signals for large State Management

Discussão em 'Angular' iniciado por Dranna, Outubro 21, 2024.

  1. Dranna

    Dranna Guest

    Evaluating architecture for a rework of our application in modern Angular, I find Signals to be great candidates for state management.

    However, our application is quite large, and playing with some ideas, I am finding some pitfalls.

    1. The first design wraps a custom AppState in a Signal

    @Injectable()
    export class AppStateService {
    private appState = signal(new AppState());


    public getState() {
    return this.appState.asReadonly();
    }

    public setForm(form: FormGroup) {
    this.appState.update(state => {
    state.form = form;
    return state;
    })
    }

    public addError(error: AppError) {
    this.appState.update(state => {
    state.errors.push(error)
    return state;
    })
    }
    }


    But I understand this is not efficient as changing one part of the state will re-evaluate every dependent code.

    1. With a second design, I investigated @ngrx/signals, thinking the concept of 'fine-grained reactivity' and nested/deep signals would solve this issue:

    export const AppStore = signalStore(
    withState(initialAppState),
    withMethods((store) => ({
    addError: (error: AppError): void => {
    patchState(store, (state) => ({ errors: [...state.errors, error] }));
    },
    setForm: (form: FormGroup): void => {
    patchState(store, (state) => ({ form: form }));
    },
    debug: (): any => {
    const state = store.form().getRawValue(); // Trying a "partial" state use
    return state;
    },
    })),
    );


    But in this second example, if I use the debug() function in the code, I noticed at least two issues:

    • If I call the method twice in the template, it is called twice. I know it is not ideal and I could solve this with template variables, but I was still expecting some kind of memoization?
    • My biggest complain; even with this partial use, which only uses the nested signal form, if I push a value in errors, this method is re-evaluated, while we know nothing has changed in form

    Is there a better way for state management? Should I just give up with centralized state management and split in different states by concern? I worry that this might lead to spaghetti code, when I will need one sub-state change to have side-effects on others. And I don't see the value of @ngrx/signals over a single big state for performance/reactivity.

    Continue reading...

Compartilhe esta Página