Entonces, imagina que tienes una tienda ngrx con una lista de libros.
Cuando inicia sesión en su página de perfil, obtiene sus libros usando:
this.store.dispatch(getBooks());Lo que activará el efecto:
getBooks$ = createEffect(() => this.actions.pipe( ofType(A.getBooks), switchMap(() => this.bookService.getBooks().pipe( map((books) => A.getBooksOk({ books })), catchError(() => EMPTY), ), ), ), );Sin embargo, no desea que este efecto se active cada vez que navega a su página de perfil, ya que solo necesita obtener los libros una vez.
Entonces agregas take(1) :
getBooks$ = createEffect(() => this.actions.pipe( ofType(A.getBooks), take(1), switchMap(() => ...El problema ahora es que si cierra sesión y luego inicia sesión en otro perfil, la tienda no obtendrá sus libros porque el perfil anterior ya ha activado el efecto.
La solución obvia a esto sería no usar take(1) y, en su lugar, tener otra variable booksLoaded en la tienda que puede usar para verificar si debe obtener los libros o no.
Sin embargo, esto es bastante tedioso ya que necesitaría una de estas variables 'cargadas' para cada variable en la tienda y agregar un montón de código adicional para administrar estas variables.
Entonces, la pregunta es: ¿hay alguna manera de hacer que un efecto solo se active una vez (como take(1) ), pero luego, cuando cierra la sesión y vuelve a iniciarla, permite que el efecto se active nuevamente (solo una vez)?
Editar : también puede verificar si los libros no están definidos en el efecto. Sin embargo, el efecto aún podría activarse varias veces antes de obtener la respuesta del servidor, por lo que no siempre funcionaría.
No sé por qué crees que es una molestia comprobar si ya tienes datos. No necesita una nueva variable necesariamente, solo verifique si sus resultados ya están configurados.
getBooks$ = createEffect(() => this.actions.pipe( ofType(A.getBooks), withLatestFrom(this.store.select(S.selectBooks)), exhaustMap(([, books]) => iif( () => books, of(A.getBooksOk({ books })), this.bookService.getBooks().pipe( map((books) => A.getBooksOk({ books })), catchError(() => EMPTY), ), ), ), ), );Solo asegúrese de vaciar sus libros en su reductor donde tenga sentido (como cuando cierra la sesión).