ngrx 中的不可变状态有问题
having problem with immutable state in ngrx
我是 ngrx 的新手。试图使不可变状态起作用,但它似乎对我不起作用。
我这里有一个减速器:
https://stackblitz.com/edit/brewbrut?file=src%2Fapp%2Fstate%2Fbreweries.reducer.ts
breweryDetails 应该 return 一个新数组(状态),包含过滤后的结果。如果我点击一个啤酒厂,而不是返回,或者点击导航回啤酒厂列表的 link,状态仍然被过滤。
这里是 stackblitz:https://brewbrut.stackblitz.io/
这里是减速器:
import { createReducer, on } from "@ngrx/store";
import { IBrewery } from "../definitions/brewery.definition";
import {
retrievedBreweries,
listAllBreweries,
breweryDetails
} from "./breweries.actions";
export const initialState: ReadonlyArray<IBrewery> = [];
export const breweriesReducer = createReducer(
initialState,
on(retrievedBreweries, (state, { breweries }) => [...state, ...breweries]),
on(listAllBreweries, state => state),
on(breweryDetails, (state, { breweryId }) =>
state.filter(brewery => brewery.id === breweryId)
)
);
我做错了什么?
我调查了你的代码,
实际上,您的代码可以正常工作,没有任何变化,
当你select一些啤酒厂
时,你只需清除所有啤酒厂
在这种情况下,您应该为 selected Brewery
创建一个单独的 属性 商店
所以我更改了您的 AppState,我为所有 brews 创建了一个 属性,其中包括
breweries
和 selected
。
现在看起来像:
import { ActionReducerMap } from "@ngrx/store";
import { IBrewery } from "../definitions/brewery.definition";
import { breweriesReducer } from "./breweries.reducer";
export interface AppState {
brews: Brews;
}
export interface Brews {
breweries: ReadonlyArray<IBrewery>;
selected: IBrewery;
}
export const reducers: ActionReducerMap<AppState> = {
brews: breweriesReducer
};
也在app.module中更改了主减速器
@NgModule({
declarations: [AppComponent, HeaderComponent, FooterComponent],
imports: [
BrowserModule,
BrowserTransferStateModule,
AppRoutingModule,
HttpClientModule,
CoreModule,
BrowserAnimationsModule,
StoreModule.forRoot(reducers)
],
providers: [],
bootstrap: [AppComponent]
})
我也对你的减速器做了一点改动:
import { createReducer, on } from "@ngrx/store";
import { IBrewery } from "../definitions/brewery.definition";
import { retrievedBreweries, breweryDetails } from "./breweries.actions";
export const initialState = {
breweries: [],
selected: null
};
export const breweriesReducer = createReducer(
initialState,
on(retrievedBreweries, (state, { breweries }) => ({
...state,
breweries
})),
on(breweryDetails, (state, { breweryId }) => ({
...state,
selected: [...state.breweries].filter(brewery => brewery.id === breweryId)
}))
);
我在 BreweriesComponent 和 BreweryComponent 中使用了一个简单的箭头函数(可以更简单),而不是你的 select:
ngOnInit(): void {
this.breweries$ = this.store
.select(s => s.brews.breweries)
.pipe(takeUntil(this.destroy$));
}
在这里您可以找到完整的(编辑过的)项目:
https://stackblitz.com/edit/brewbrut-envssk?file=src/app/state/breweries.reducer.ts
我是 ngrx 的新手。试图使不可变状态起作用,但它似乎对我不起作用。
我这里有一个减速器: https://stackblitz.com/edit/brewbrut?file=src%2Fapp%2Fstate%2Fbreweries.reducer.ts
breweryDetails 应该 return 一个新数组(状态),包含过滤后的结果。如果我点击一个啤酒厂,而不是返回,或者点击导航回啤酒厂列表的 link,状态仍然被过滤。
这里是 stackblitz:https://brewbrut.stackblitz.io/
这里是减速器:
import { createReducer, on } from "@ngrx/store";
import { IBrewery } from "../definitions/brewery.definition";
import {
retrievedBreweries,
listAllBreweries,
breweryDetails
} from "./breweries.actions";
export const initialState: ReadonlyArray<IBrewery> = [];
export const breweriesReducer = createReducer(
initialState,
on(retrievedBreweries, (state, { breweries }) => [...state, ...breweries]),
on(listAllBreweries, state => state),
on(breweryDetails, (state, { breweryId }) =>
state.filter(brewery => brewery.id === breweryId)
)
);
我做错了什么?
我调查了你的代码,
实际上,您的代码可以正常工作,没有任何变化,
当你select一些啤酒厂
时,你只需清除所有啤酒厂在这种情况下,您应该为 selected Brewery
创建一个单独的 属性 商店所以我更改了您的 AppState,我为所有 brews 创建了一个 属性,其中包括
breweries
和 selected
。
现在看起来像:
import { ActionReducerMap } from "@ngrx/store";
import { IBrewery } from "../definitions/brewery.definition";
import { breweriesReducer } from "./breweries.reducer";
export interface AppState {
brews: Brews;
}
export interface Brews {
breweries: ReadonlyArray<IBrewery>;
selected: IBrewery;
}
export const reducers: ActionReducerMap<AppState> = {
brews: breweriesReducer
};
也在app.module中更改了主减速器
@NgModule({
declarations: [AppComponent, HeaderComponent, FooterComponent],
imports: [
BrowserModule,
BrowserTransferStateModule,
AppRoutingModule,
HttpClientModule,
CoreModule,
BrowserAnimationsModule,
StoreModule.forRoot(reducers)
],
providers: [],
bootstrap: [AppComponent]
})
我也对你的减速器做了一点改动:
import { createReducer, on } from "@ngrx/store";
import { IBrewery } from "../definitions/brewery.definition";
import { retrievedBreweries, breweryDetails } from "./breweries.actions";
export const initialState = {
breweries: [],
selected: null
};
export const breweriesReducer = createReducer(
initialState,
on(retrievedBreweries, (state, { breweries }) => ({
...state,
breweries
})),
on(breweryDetails, (state, { breweryId }) => ({
...state,
selected: [...state.breweries].filter(brewery => brewery.id === breweryId)
}))
);
我在 BreweriesComponent 和 BreweryComponent 中使用了一个简单的箭头函数(可以更简单),而不是你的 select:
ngOnInit(): void {
this.breweries$ = this.store
.select(s => s.brews.breweries)
.pipe(takeUntil(this.destroy$));
}
在这里您可以找到完整的(编辑过的)项目:
https://stackblitz.com/edit/brewbrut-envssk?file=src/app/state/breweries.reducer.ts