I have a component with a simple login form. @Component({ selector: 'app-login', standalone: true, imports: [ ReactiveFormsModule, MatCardModule, ... ], templateUrl: './login.component.html', styleUrl: './login.component.scss', }) export class LoginComponent implements OnInit { constructor( private route: ActivatedRoute, private router: Router, private formService: FormService, private appUserStore: AppUserStore, ) { this.isLoading = this.appUserStore.isLoading; effect(() => { if (this.appUserStore.isLogged()) { this.router.navigate([this.returnUrl]); } }); } returnUrl = '/'; isLoading = signal(false).asReadonly(); loginForm: FormGroup<LoginForm> = new FormGroup<LoginForm>({ login: new FormControl('', { validators: [Validators.required, Validators.minLength(2)], nonNullable: true, }), password: new FormControl('', { validators: [ Validators.required, Validators.minLength(4), Validators.maxLength(50), ], nonNullable: true, }), }); ngOnInit(): void { this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; } onLogin() { this.appUserStore.login(this.loginForm.getRawValue()); } } A simple user state store was prepared for authorization and storage of user state. The store was created based on NgRx SignalState, based on the documentation signal-state. My user state store is not complete yet. interface AppUserState { user: User; isLoading: boolean; isLogged: boolean; tokens: Tokens; } const initialState: AppUserState = { user: new User(), isLoading: false, isLogged: false, tokens: new Tokens('', '', 0), }; @Injectable({ providedIn: 'root', }) export class AppUserStore { private readonly state = signalState<AppUserState>(initialState); private readonly authService = inject(AuthApiService); private readonly tokenCookieService = inject(TokenCookieService); readonly user = this.state.user; readonly isLogged = this.state.isLogged; readonly isLoading = this.state.isLoading; readonly login = rxMethod<LoginData>( pipe( tap(() => patchState(this.state, { isLoading: true })), exhaustMap((loginData: LoginData) => { return this.authService.login(loginData).pipe( tapResponse({ next: (loginResponse) => { this.tokenCookieService.saveTokensCookie(loginResponse.tokens); patchState(this.state, { user: loginResponse.user, tokens: loginResponse.tokens, isLogged: loginResponse.user.id > 0, }); }, error: (error) => { this.resetState(); console.log(error); }, finalize: () => patchState(this.state, { isLoading: false }), }), ); }), ), ); private readonly resetState = () => { this.tokenCookieService.deleteTokensCookie(); patchState(this.state, { ...initialState }); }; } Theoretically the component works as expected. After changing the login state, it redirects to the next url. My main question is whether "effect" used to detect a change in the user's login state is a correct solution. While searching for a solution on the Internet, I came across an opinion that "effect" should be used in specific cases. You should use "computed" to react to a change in the signal value, but I was unable to achieve the expected behavior of the component. I know that you can use "toObservable" from rxjs-interop to transform the signal to an observable, and then make a subscription. But is this a necessary and the only correct solution? Continue reading...