angular - Egenskaben 'payload' findes ikke på typen 'Action', når man opgraderer @ngrx/Store


Jeg har @ngrx/store-pakken i min Angular (4.x) app, og opgraderer fra v2.2.2 -> v4.0.0. Jeg kan se, at migrationsnoterne siger:

Payload-egenskaben er blevet fjernet fra Action-interface.

Dog virker det eksempel, de giver, helt kontraintuitivt (efter min mening...).

Jeg har en reducer-funktion, som ser sådan ud:

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

Hvilket som forventet nu udløser en TypeScript-fejl:

[ts] Egenskaben 'payload' findes ikke på typen 'Action'

Men jeg har ingen idé ud fra migrationsguiden, hvad dette skal ændres til. Nogle idéer?

Svar #1

Du kan oprette din egen handlingstype, der har en payload defineret, se eksempelappen som reference:

class AddBookAction implements Action {
    readonly type = ADD_BOOK;

    constructor(public payload: Book) {}
}

Brug derefter den type i reducerefunktionen:

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

Handling kunne udsendes sådan her:

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

Bemærk også, at eksempelappen kombinerer alle de handlingstyper, som en reducer kan udføre, i en enkelt unionstype:

export type Actions =
    | AddBookAction
    | AddBookSuccessAction

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

Svar #2

Ok, det er et meget interessant emne. Jeg gik glip af den nye udgivelse (4.0), men jeg opdaterede bibliotekerne i mit repo, og jeg så, at jeg har det samme problem.

Det er korrekt. Payload-attributten blev slettet fra Action i den nye udgivelse. Hvis du bruger effekter til at dispatch action, er løsningen simpel, og du kan læse om dem i migrationsnoterne

men hvis du vil have dispatch til at sende payload, kan du oprette en parametriseret Action på denne måde:

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

så hvis du tilføjede dette interface, kan du ændre reducer på denne måde:

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

Det er den bedste løsning, jeg har fundet. Jeg skal forstå bedre årsagen til denne ændring, og hvis jeg finder en bedre løsning, tilføjer jeg dem her.

Relaterede artikler