NgRx createReducer() 和 on() 给出错误
Posted
技术标签:
【中文标题】NgRx createReducer() 和 on() 给出错误【英文标题】:NgRx createReducer() and on() is giving error 【发布时间】:2021-05-24 09:47:06 【问题描述】:我是新人。到 NgRx。
当我尝试使用 createReducer()
创建减速器时,我收到错误 Expected 4 arguments, but got 2.
当我尝试将第 3 和第 4 个参数作为 null 传递时,出现错误
Argument of type '(state: any, updatedValue : any) => any' is not assignable to parameter of type 'readonly ActionCreator<string, FunctionWithParametersType<any[], object>>[]'.
Type '(state: any, updatedValue : any) => any' is missing the following properties from type 'readonly ActionCreator<string, FunctionWithParametersType<any[], object>>[]': concat, join, slice, indexOf, and 15 more.ts(2345)
reducer 代码
import createReducer, on, State, Action from '@ngrx/store';
import Ingredient from '../../shared/ingredient.model';
import * as ShoppingListAction from './shopping-list.action';
export const initialState =
ingredients: [
new Ingredient('Apples', 5),
new Ingredient('Tomatoes', 10),
]
export const shoppingListReducer = createReducer(
initialState,
on(
'ADD_INGREDIENT',
(state: any, updatedValue : any) => ( ...state, prop: updatedValue ),
null,
null
)
);
动作代码
import createAction, props from '@ngrx/store';
import Ingredient from '../../shared/ingredient.model';
export const ADD_INGREDIENT = 'ADD_INGREDIENT';
export const AddIngredient = createAction(
ADD_INGREDIENT,
props<Ingredient>()
);
app.module.ts
import SharedModule from './shared/shared.module';
import CoreModule from './core.module';
import LoggingService from './logging.service';
// Store
import shoppingListReducer from './shopping-list/store/shopping-list.reducer';
@NgModule(
declarations: [AppComponent, HeaderComponent],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
SharedModule,
CoreModule,
StoreModule.forRoot( 'slReduce': shoppingListReducer )
],
bootstrap: [AppComponent],
// providers: [LoggingService]
)
export class AppModule
package.json
"dependencies":
"@angular/animations": "^11.2.1",
"@angular/common": "^11.2.1",
"@angular/compiler": "^11.2.1",
"@angular/core": "^11.2.1",
"@angular/forms": "^11.2.1",
"@angular/platform-browser": "^11.2.1",
"@angular/platform-browser-dynamic": "^11.2.1",
"@angular/router": "^11.2.1",
"@ngrx/store": "^11.0.1",
"bootstrap": "3.3.7",
"core-js": "^3.1.2",
"rxjs": "^6.0.0",
"tslib": "^2.0.0",
"zone.js": "~0.11.3"
【问题讨论】:
【参考方案1】:我在我的 IDE 中看到了这个错误,以及与 @ngrx/store 相关的其他一些奇怪的类型相关错误,但项目编译得很好。
我已将我的项目中使用 @ngrx 的 typescript 版本升级到最新版本(当时是 v4.3.4),但我的工作区包括其他几个项目,我的 IDE(我正在使用 WebStorm)typescript 语言服务是配置为使用安装在我的其他项目之一上的旧版打字稿。将 IDE typescript 服务配置为使用较新的 typescript 版本后,错误就消失了。
所以在我的情况下,这是几件不同的事情 - 首先,我需要为使用 @ngrx 的项目升级 typescript 版本,以便与一些更新的项目一起工作@ngrx 正在使用的语言功能。然后,我还必须确保我的 IDE 的打字稿语言服务正在使用该版本,或者至少是相当新的打字稿版本,以避免在编辑器窗口中看到虚假错误.
【讨论】:
【参考方案2】:确保您的@ngrx/store 库版本和您安装的@angular/core 版本不匹配。
通常它们应该使用相同的主要版本 - 对于@angular/core ^9.x.x,您应该使用相应的 ^9.x.x 版本的@ngrx/store。这发生在我使用 Angular 9 并安装最新、稳定的 ngrx 版本(目前是 11.x.x)时。
阅读有关要求的更多信息(链接参考 V9,但也可以申请更新的):https://ngrx.io/guide/migration/v9
【讨论】:
【参考方案3】:你的动作和减速器看起来很奇怪。根据文档,它应该是这样的:
export interface MyState
ingredients: Array<Ingredient>;
export const initialState: MyState =
ingredients: [
new Ingredient('Apples', 5),
new Ingredient('Tomatoes', 10),
]
// see https://ngrx.io/guide/store/actions
// note: the prop has a 'name: Type', not just 'Type'
export const AddIngredient = createAction(
ADD_INGREDIENT,
props<ingredient: Ingredient>()
);
// verbose func to show difference
export const shoppingListReducer = createReducer(
initialState,
on(
AddIngredient, // the action, not the action.type
(state, ingredient ) =>
let ingredients = Array.from(state.ingredients);
ingredients.push(ingredient);
return ingredients ;
)
);
或者,如果您更喜欢简写:
// equal shorthand function
export const shoppingListReducer = createReducer(
initialState,
on(
AddIngredient, // the action, not the action.type
(state, ingredient ) => (ingredients: [...state.ingredients, ingredient])
)
);
主要有以下几点:
(state: any, updatedValue : any) => ( ...state, prop: updatedValue )
需要一个带有名为 updatedValue 的道具的动作(与动作相比,道具现在命名为成分)
返回一个从当前状态组装的对象和一个名为 prop (*) 的字段
(*) 如果这行得通,它会导致类似的状态
interface MyAccidentalState
ingredients: Array<Ingredient>;
prop: Ingredient;
...但它不起作用,因为您的操作没有命名道具“updatedValue”并且prop: updatedValue
不是prop: updatedValue
。
并且因为它没有命名的 prop 'updatedValue',编译器在对象解构部分爆炸
(state: any, updatedValue : any) => ...
(state: any, updatedValue : any) => ...
中的任何类型可能会否认编译器已经存在的一些知识:updatedValue 旨在成为一种成分,而 state 是(现在)一个 MyState。
旁注:
保持集合的状态是 ngrx/entity 可能有用的东西 - 但你的方式也是有效的。
【讨论】:
此代码对我不起作用 - 出现与 OP 相同的错误以上是关于NgRx createReducer() 和 on() 给出错误的主要内容,如果未能解决你的问题,请参考以下文章
带有 PWA 和 Service Worker 的 NGRX 离线缓存