升级 @ngrx/Store 时 属性 'payload' 在类型 'Action' 上不存在
Property 'payload' does not exist on type 'Action' when upgrading @ngrx/Store
我的 angular (4.x) 应用程序中有 @ngrx/store
包,我正在从 v2.2.2 升级 -> v4.0.0。我可以看到迁移说明说:
The payload property has been removed from the Action interface.
然而,他们给出的例子似乎完全违反直觉(在我看来......)。
我有一个 reducer 函数,如下所示:
export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: Action): ITitle {
switch (action.type) {
case 'SET_TITLE':
return {
company: action.payload.company,
site: action.payload.site,
department: action.payload.department,
line: action.payload.line
}
case 'RESET':
return {
company: 'MyCo',
site: 'London'
}
default:
return state
}
}
如预期的那样现在抛出打字稿错误:
[ts] Property 'payload' does not exist on type 'Action'
但是我从迁移指南中不知道应该更改什么。有什么想法吗?
您可以创建自己的动作类型,其中定义了 payload
,检查 the example app 以供参考:
class AddBookAction implements Action {
readonly type = ADD_BOOK;
constructor(public payload: Book) {}
}
然后在 the reducer 中使用该类型:
function reducer(state = initialState, action: AddBookAction): State
动作可以像 this:
一样发送
this.store.dispatch(new AddBookAction(book));
另请注意示例应用程序 combines reducer 可以将所有操作类型合并为一个联合类型:
export type Actions =
| AddBookAction
| AddBookSuccessAction
export function reducer(state = initialState, action: Actions): State
好的,这是一个非常有趣的话题。我错过了新的 realese (4.0),但我更新了我的 repo 中的库,我发现我遇到了同样的问题。
没错。新版本中的 Action 中删除了 Payload 属性。如果你使用效果来调度动作,解决方案很简单,你能在migration note
中阅读它们吗
但是如果你想dispatch传递payload,你可以这样创建参数化的Action:
export interface ActionWithPayload<T> extends Action {
payload: T;
}
所以如果你添加了这个接口,你可以这样改变 reducer:
export class SomeObject {
company: string;
site: string;
department: string;
line: string;
}
export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: ActionWithPayload<SomeObject>): ITitle {
switch (action.type) {
case 'SET_TITLE':
return {
company: action.payload.company,
site: action.payload.site,
department: action.payload.department,
line: action.payload.line
}
...
这是我发现的最好的解决方法。我必须更好地理解此更改的原因,如果我能找到更好的解决方案,我会在此处添加它们
我还发现这种方法很有用:使用 as
子句导入原始 Action
接口并使用 payload
属性 对其进行扩展。
在这种情况下,无需更改其余代码:https://blog.dmbcllc.com/upgrade-ngrx-4-x/。
我在这里看到了同样的错误消息,但有另一个原因:
在我的生成器上,我有类似的东西:
.addCase(setFlight.type, (state, action) => {
state.flight = action.payload
});
像这样的动作:
const setFlight = createAction<Flight>('flight/set');
然后总是得到错误“payload does not exist on type action”,我应该做的是在 .addCase()
的第一个参数中删除 type
,所以 reducer 应该看起来像这样:
.addCase(setFlight, (state, action) => {
state.flight = action.payload
});
现在 payload
在下拉菜单中可用并且错误消失了。
请在 app.module.ts
中进行更改
imports: [
StoreModule.forRoot({ appTutorial: TutorReducer } as ActionReducerMap<any,any>),
]
它可以消除错误。
我的 angular (4.x) 应用程序中有 @ngrx/store
包,我正在从 v2.2.2 升级 -> v4.0.0。我可以看到迁移说明说:
The payload property has been removed from the Action interface.
然而,他们给出的例子似乎完全违反直觉(在我看来......)。
我有一个 reducer 函数,如下所示:
export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: Action): ITitle {
switch (action.type) {
case 'SET_TITLE':
return {
company: action.payload.company,
site: action.payload.site,
department: action.payload.department,
line: action.payload.line
}
case 'RESET':
return {
company: 'MyCo',
site: 'London'
}
default:
return state
}
}
如预期的那样现在抛出打字稿错误:
[ts] Property 'payload' does not exist on type 'Action'
但是我从迁移指南中不知道应该更改什么。有什么想法吗?
您可以创建自己的动作类型,其中定义了 payload
,检查 the example app 以供参考:
class AddBookAction implements Action {
readonly type = ADD_BOOK;
constructor(public payload: Book) {}
}
然后在 the reducer 中使用该类型:
function reducer(state = initialState, action: AddBookAction): State
动作可以像 this:
一样发送this.store.dispatch(new AddBookAction(book));
另请注意示例应用程序 combines reducer 可以将所有操作类型合并为一个联合类型:
export type Actions =
| AddBookAction
| AddBookSuccessAction
export function reducer(state = initialState, action: Actions): State
好的,这是一个非常有趣的话题。我错过了新的 realese (4.0),但我更新了我的 repo 中的库,我发现我遇到了同样的问题。
没错。新版本中的 Action 中删除了 Payload 属性。如果你使用效果来调度动作,解决方案很简单,你能在migration note
中阅读它们吗但是如果你想dispatch传递payload,你可以这样创建参数化的Action:
export interface ActionWithPayload<T> extends Action {
payload: T;
}
所以如果你添加了这个接口,你可以这样改变 reducer:
export class SomeObject {
company: string;
site: string;
department: string;
line: string;
}
export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: ActionWithPayload<SomeObject>): ITitle {
switch (action.type) {
case 'SET_TITLE':
return {
company: action.payload.company,
site: action.payload.site,
department: action.payload.department,
line: action.payload.line
}
...
这是我发现的最好的解决方法。我必须更好地理解此更改的原因,如果我能找到更好的解决方案,我会在此处添加它们
我还发现这种方法很有用:使用 as
子句导入原始 Action
接口并使用 payload
属性 对其进行扩展。
在这种情况下,无需更改其余代码:https://blog.dmbcllc.com/upgrade-ngrx-4-x/。
我在这里看到了同样的错误消息,但有另一个原因:
在我的生成器上,我有类似的东西:
.addCase(setFlight.type, (state, action) => {
state.flight = action.payload
});
像这样的动作:
const setFlight = createAction<Flight>('flight/set');
然后总是得到错误“payload does not exist on type action”,我应该做的是在 .addCase()
的第一个参数中删除 type
,所以 reducer 应该看起来像这样:
.addCase(setFlight, (state, action) => {
state.flight = action.payload
});
现在 payload
在下拉菜单中可用并且错误消失了。
请在 app.module.ts
imports: [
StoreModule.forRoot({ appTutorial: TutorReducer } as ActionReducerMap<any,any>),
]
它可以消除错误。