繁体   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