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 创建了一个 属性,其中包括 breweriesselected 。 现在看起来像:

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