升级@ngrx/Store 时,类型“操作”上不存在属性“有效负载”

Posted

技术标签:

【中文标题】升级@ngrx/Store 时,类型“操作”上不存在属性“有效负载”【英文标题】:Property 'payload' does not exist on type 'Action' when upgrading @ngrx/Store 【发布时间】:2018-01-06 19:44:53 【问题描述】:

我的 Angular (4.x) 应用程序中有 @ngrx/store 包,并且正在从 v2.2.2 -> v4.0.0 升级。我可以看到迁移说明说:

payload 属性已从 Action 接口中移除。

然而,他们给出的例子似乎完全违反直觉(在我看来......)。

我有一个 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] 类型“操作”上不存在属性“有效负载”

但是我从迁移指南中不知道这也应该改变。有什么想法吗?

【问题讨论】:

你能显示 Action 类的导入吗? @JaroslawK。 import ActionReducer, Action from '@ngrx/store'; 好的,您能展示一下您是如何使用有效负载调用 Action 的吗?实际上或其他方式 @JaroslawK。我不太清楚你的意思,上面是我的减速器功能,然后我将它提供给我的应用程序模块,然后在我的组件中提供.select('title')。我不会在任何地方直接调用 Action 我说的是,你在哪里调度 Action(.dispatch(new Action() or Effect) 【参考方案1】:

您可以创建自己的操作类型并定义了 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));

还要注意示例应用程序combinesreducer 可以将所有操作类型纳入单个联合类型:

export type Actions =
    | AddBookAction
    | AddBookSuccessAction

export function reducer(state = initialState, action: Actions): State

【讨论】:

在比较了github.com/ngrx/platform/issues/31 上的 elvirdolic 解决方案和 SO 上的其他答案之后,这是最好的方法。创建动作类,创建实现动作的自定义动作类型并添加payload属性,然后调度动作类。干净且类型更强的解决方案。 在此解决方案中需要注意的一点是,您不应将类型变量声明为某些打字稿变量类型。例如(只读类型:string = ADD_BOOK;)将不起作用! (如果我们假设 ADD_BOOK 常量被定义为一个字符串)。【参考方案2】:

好的,这是一个非常有趣的话题。我错过了新的 realese(4.0),但我更新了我的仓库中的库,我发现我有同样的问题。

没错。在新版本中,有效负载属性已从操作中删除。如果您使用效果来调度动作,解决方案很简单,您可以在migration note中阅读它们

但是如果你希望 dispatch 传递有效载荷,你可以通过这种方式创建参数化 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
            
            ...

这是我发现的最好的解决方法。我必须更好地理解这种变化的原因,如果我能找到更好的解决方案,我会在这里添加它们

【讨论】:

太棒了,谢谢。如果我确实使用效果会是什么样子? 我不确定我是否理解您的问题。您是在问如果使用 ActionWithPayload 效果如何? 我在问你的评论“如果你使用效果来调度动作,解决方案很简单”,我不明白迁移笔记之前和之后发生了什么 所以我想知道基于效果的解决方案可能是什么样子?【参考方案3】:

我还发现这种方法很有帮助:使用as 子句导入原始Action 接口并使用payload 属性对其进行扩展。

在这种情况下,无需更改其余代码:https://blog.dmbcllc.com/upgrade-ngrx-4-x/。

【讨论】:

以上是关于升级@ngrx/Store 时,类型“操作”上不存在属性“有效负载”的主要内容,如果未能解决你的问题,请参考以下文章

ngrx/store@6.1.0 在升级到 Angular 7 时需要 @angular/core@^6.0.0 的对等体

NGRX/Store 有效载荷类型混淆

调度 @ngrx/router-store 操作时出现 Redux devtools 扩展错误

安装@ngrx/store 时如何清除错误?

来自 ngrx 的关于运行时检查的警告

如何在 @ngrx/store 的 createAction 中使用数组作为参数