Tengo una implementación redux básica con ngrx/store.
// reductor de raíz
export const root = { posts: fromPosts.reducer, purchases: fromPurchases.reducer } export function getAllPosts( state ) { return fromPosts.getAll(state.posts); } export function getAllPurchases( state ) { return fromPurchases.getAll(state.purchases); }En mi componente, estoy seleccionando las piezas de estado.
this.posts$ = store.select(getAllPosts).do(c => console.log('posts$ change')); this.purchases$ = store.select(getAllPurchases).do(c => console.log('purchases$ change')); Pero en cada cambio de estado, ambos controladores se ejecutan. Por ejemplo, cuando agrego una publicación, el controlador purchases$ también se ejecuta.
Todo el punto es ejecutar solo la parte que cambió, ¿o estoy equivocado?
Esta respuesta es incorrecta, pero, por alguna razón, fue aceptada. La implementación de select usa distinctUntilChanged , por lo que es probable que el problema resida en las implementaciones de las funciones getAll del OP.
Cada vez que se envía una acción a la tienda, se pasa a los reductores compuestos y se compone un nuevo estado. Entonces se emite ese nuevo estado.
Entonces, ambos observables verán un valor emitido a los operadores do , incluso cuando la porción de estado seleccionada no haya cambiado.
Sin embargo, es simple cambiar este comportamiento usando el operador distinctUntilChanged :
import 'rxjs/add/operator/distinctUntilChanged'; this.posts$ = store.select(getAllPosts) .distinctUntilChanged() .do(c => console.log('posts$ change')); distinctUntilChanged se asegurará de que el observable solo se emita cuando el valor realmente haya cambiado, por lo que si la porción de estado que está seleccionando no ha cambiado, no se emitirá nada.
Tus selectores no usan createSelector.
Cuando se usa createSelector y cuando cambia el estado, createSelector memoriza el valor de retorno en función de sus valores de parámetro.
Cuando se vuelve a llamar a la función definida con createSelector con los mismos parámetros memorizados, se proporciona el valor de retorno y el resto del código del selector no se ejecuta.
/** * Every reducer module exports selector functions, however child reducers * have no knowledge of the overall state tree. To make them usable, we * need to make new selectors that wrap them. * * The createSelector function creates very efficient selectors that are memoized and * only recompute when arguments change. The created selectors can also be composed * together to select different pieces of state. */ export const getBookEntitiesState = createSelector( getBooksState, state => state.books );Ejemplo de uso (aunque este es un hilo antiguo y el ejemplo es de un NGRX más nuevo) https://github.com/ngrx/platform/blob/master/example-app/app/books/reducers/index.ts#L58
Dado que la implementación de select usa distintUntilChanged , y
distinguibleUntilChanged utiliza la comparación === de forma predeterminada, las referencias a los objetos deben coincidir. https://www.learnrxjs.io/operators/filtering/distinctuntilchanged.html
probablemente el problema radica en el hecho de que no importa qué acción se envíe a su reducer , devuelve una nueva referencia del estado (incluso cuando el valor del estado no se ha cambiado).
verifique su declaración de cambio de reductor, la sección predeterminada, probablemente copia en profundidad el estado cuando no se cambian los valores, por lo tanto, devuelve una nueva referencia y el selector se ejecuta nuevamente.