簡體   English   中英

Angular 2 - ngrx訂閱運行每個狀態更改

[英]Angular 2 - ngrx subscribe running on every state change

我有一個基本的redux實現與ngrx / store。

// root reducer

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);
}

在我的組件中,我正在選擇州塊。

this.posts$ = store.select(getAllPosts).do(c => console.log('posts$ change'));
this.purchases$ = store.select(getAllPurchases).do(c => console.log('purchases$ change'));

但是在狀態的每次更改中,處理程序都在運行。 例如,當我添加帖子時, purchases$ handler也會運行。

所有的一點是只運行改變的部分,或者我錯了?

這個答案是錯誤的,但由於某種原因,它被接受了。 select的實現使用distinctUntilChanged ,因此問題可能存在於OP的getAll函數的實現中。

每當將一個動作發送到商店時,它就會傳遞給組合的減速器並組成一個新的狀態。 然后發出新的狀態。

因此,即使選定的狀態切片未發生變化,您的兩個可觀察對象都會看到向do運算符發出的值。

但是,使用distinctUntilChanged運算符更改此行為很簡單:

import 'rxjs/add/operator/distinctUntilChanged';

this.posts$ = store.select(getAllPosts)
  .distinctUntilChanged()
  .do(c => console.log('posts$ change'));

distinctUntilChanged將確保observable僅在值實際更改時發出,因此如果您選擇的狀態切片未更改,則不會發出任何內容。

您的選擇器未使用createSelector。

使用createSelector時和狀態更改時,createSelector會根據其參數值記憶返回值。

當使用相同參數再次調用使用createSelector定義的函數時,將給出memoized返回值,並且不會運行選擇器代碼的其余部分。

/**
 * 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
);

示例使用(雖然這是一個舊線程,示例來自較新的NGRX) https://github.com/ngrx/platform/blob/master/example-app/app/books/reducers/index.ts#L58

由於select的實現使用了distinctUntilChanged,和

distinctUntilChanged默認使用===比較,對象引用必須匹配。 https://www.learnrxjs.io/operators/filtering/distinctuntilchanged.html

可能問題在於,無論調度到您的reducer的操作是什么,都會返回狀態的新引用(即使狀態值尚未更改)。

檢查你的reducer switch語句,默認部分,可能是在沒有更改值時深度復制狀態 - 因此返回一個新引用並再次執行選擇器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM