在 init hook 中选择存储切片时如何解决这个无限循环?
实例化组件时,我需要用一系列道具来派遣一项动作,这些操作将通过又会获取数据的效果来处理。此操作后,我需要更新状态并保存此搜索的标准。我理解的最后一件事会导致无尽的循环
更新0
我找到了这个问题如何访问以前的状态和当前状态并在您订阅ngrx中的商店时进行比较吗?,建议使用为了仅派遣组件实例化的操作,我使用
distionuntilChanged
。在更改startDate
或endDate
的值时,我希望它执行,但这不会发生,它根本不会执行。有什么想法吗?
this.store
.pipe(
select('dashboard'),
distinctUntilChanged(
(prev, curr) =>
prev.startDate === curr.startDate || prev.endDate === curr.endDate
)
)
.subscribe({
next: (state) => {
this.startDate = state.startDate;
this.endDate = state.endDate;
// ...
this.store.dispatch(
filter({
startDate: this.startDate,
endDate: this.endDate
})
);
},
});
组件类
ngOnInit(): void {
this.store.select('dashboard').subscribe({
next: (state) => {
this.startDate = state.startDate;
this.endDate = state.endDate;
// ...
this.store.dispatch(
filter({
startDate: this.startDate,
endDate: this.endDate,
})
);
},
});
}
诉讼
export const filter = createAction(
'[Dashboard component] Apply filter',
props<{
startDate: Date;
endDate: Date;
}>()
);
效果看起来与此
filter$ = createEffect(() =>
this.actions$.pipe(
ofType(filter),
switchMap((action) => {
const obs0$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs1$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs2$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs3$ = new Observable((observer: Observer<any>) => {
// ...
}
);
const obs4$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs5$ = new Observable((observer: Observer<any>) => {
// ...
});
return forkJoin<readonly SourceModel[] | readonly RankingModel[]>([
obs1$,
obs2$,
obs3$,
obs4$,
obs5$,
obs6$,
]).pipe(map((response) => filterSuccess({ payload: response })));
})
)
);
还原器看起来相似,
// ...
export interface AdminState {
startDate: Date;
endDate: Date;
}
export const initialState: AdminState = {
startDate: new Date(),
endDate: getDashboardFilterDefaultEndDate(),
};
export const adminReducer = createReducer(
initialState,
on(filter, (state, { startDate, endDate }) => ({
...state,
startDate,
endDate,
})),
on(filterSuccess, (state, { payload }) => ({
...state,
// ...
}))
);
我知道该行为是由于数据收集完成并且在还原器中更新搜索标准时,在组件开始时选择了select triggers a新搜索。如果是这样,我该如何处理?
感谢您的建议
When instantiating a component I need to dispatch an action with a series of props that will be handled by an effect that will in turn obtain data. After this operation I need to update the state and save the criteria of this search. Doing the last thing I understand causes an endless loop
Update 0
I found this question How to access previous state and current state and compare them when you subscribe to store in ngrx?, its suggested to use distinctUntilChanged
In order to only dispatch the action on the component instantiation I use distinctUntilChanged
. When changing the values of startDate
or endDate
I expect it to be executed but this does not happen, it simply does not execute. Any idea?
this.store
.pipe(
select('dashboard'),
distinctUntilChanged(
(prev, curr) =>
prev.startDate === curr.startDate || prev.endDate === curr.endDate
)
)
.subscribe({
next: (state) => {
this.startDate = state.startDate;
this.endDate = state.endDate;
// ...
this.store.dispatch(
filter({
startDate: this.startDate,
endDate: this.endDate
})
);
},
});
component class
ngOnInit(): void {
this.store.select('dashboard').subscribe({
next: (state) => {
this.startDate = state.startDate;
this.endDate = state.endDate;
// ...
this.store.dispatch(
filter({
startDate: this.startDate,
endDate: this.endDate,
})
);
},
});
}
action
export const filter = createAction(
'[Dashboard component] Apply filter',
props<{
startDate: Date;
endDate: Date;
}>()
);
effect look similar to this
filter$ = createEffect(() =>
this.actions$.pipe(
ofType(filter),
switchMap((action) => {
const obs0$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs1$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs2$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs3$ = new Observable((observer: Observer<any>) => {
// ...
}
);
const obs4$ = new Observable((observer: Observer<any>) => {
// ...
});
const obs5$ = new Observable((observer: Observer<any>) => {
// ...
});
return forkJoin<readonly SourceModel[] | readonly RankingModel[]>([
obs1$,
obs2$,
obs3$,
obs4$,
obs5$,
obs6$,
]).pipe(map((response) => filterSuccess({ payload: response })));
})
)
);
reducer look similar to this
// ...
export interface AdminState {
startDate: Date;
endDate: Date;
}
export const initialState: AdminState = {
startDate: new Date(),
endDate: getDashboardFilterDefaultEndDate(),
};
export const adminReducer = createReducer(
initialState,
on(filter, (state, { startDate, endDate }) => ({
...state,
startDate,
endDate,
})),
on(filterSuccess, (state, { payload }) => ({
...state,
// ...
}))
);
I understand that the behavior is due to the fact that when the data collection is complete and the search criteria are updated in the reducer, the select in the init of the component triggers a new search. If so, how can I handle this?
Thanks for your advice
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您必须改变消耗状态的方式。
您必须创建仅在实际更改值时才触发的选择器,如果这样做,则不必使用
distionuntilChanged
运算符。I think you have to change the way you consume the state.
You have to create selectors that are only triggered when the value is actually changed and if you do so, you won't have to use the
distinctUntilChanged
operator.