web-dev-qa-db-ja.com

@ ngrx / Storeのアップグレード時に、タイプ 'Action'にプロパティ 'payload'が存在しません

私が持っています @ngrx/store my angular(4.x)アプリのパッケージ、およびv 2.2.2-> v 4.0.からアップグレードしています。移行に関する注意事項に次のように書かれていることがわかります。

ペイロードプロパティは、Actionインターフェイスから削除されました。

しかし、彼らが与える例は完全に直観に反するように思えます(私の見解では...)。

次のようなリデューサー関数があります。

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
    }
}

予想どおり、TypeScriptエラーがスローされるようになりました。

[ts]プロパティ 'payload'はタイプ 'Action'に存在しません

しかし、移行ガイドでは、これをどのように変更すべきかわからない。何か案は?

12
George Edwards

payloadが定義された独自のアクションタイプを作成できます。参照するには、 サンプルアプリ を確認してください。

class AddBookAction implements Action {
    readonly type = ADD_BOOK;

    constructor(public payload: Book) {}
}

次に、そのタイプを リデューサー で使用します。

function reducer(state = initialState, action: AddBookAction): State

アクションは this のようにディスパッチできます:

this.store.dispatch(new AddBookAction(book));

また、例のアプリ combines は、レデューサーが単一のユニオン型に取り込むことができるすべてのアクション型であることに注意してください。

export type Actions =
    | AddBookAction
    | AddBookSuccessAction

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

わかりました、それは非常に興味深いトピックです。新しいRealese(4.0)を逃しましたが、リポジトリのライブラリを更新しましたが、同じ問題があることがわかりました。

そのとおり。ペイロード属性は、新しいリリースのアクションから削除されました。エフェクトを使用してアクションをディスパッチする場合、解決策は簡単で、 migration note で読むことができます

ただし、ディスパッチがペイロードを渡すようにする場合は、次の方法でパラメーター化されたアクションを作成できます。

export interface ActionWithPayload<T> extends Action {
  payload: T;
} 

したがって、このインターフェースを追加した場合、レデューサーを次のように変更できます。

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
            }
            ...

私が見つけた最高のウォークアラウンドです。この変更の理由をよりよく理解する必要があり、より良い解決策が見つかる場合はここに追加しました

6
Jaroslaw K.

また、このアプローチが役立つことがわかりました。元のActionインターフェースをas句でインポートし、payloadプロパティで拡張することです。

この場合、残りのコードを変更する必要はありません: https://blog.dmbcllc.com/upgrade-ngrx-4-x/

0
Peter Kassenaar