reactjs - Varför kan inte super() sättas på en oföränderlig post?


Jag sätter upp ett riktigt enkelt nytt Redux-butikstillstånd.

Jag har "klonat" en Redux-store som jag skapade tidigare och förenklat den. Jag har först försökt med bara ett state, reducer, selector och action, sedan försökte jag skapa ett träd (som i mitt äldre projekt) men inget förändrades. Jag har kontrollerat package.json och jag ser att jag har samma versioner av Redux, React, ReactRedux, Typescript, osv...

import { Record } from "immutable";

export enum officeLocations {
    cityOne = "CITYONE",
    cityTwo = "CITYTWO",
    none = "NONE",
    cityThree = "CITYTHREE",
    cityFour = "CITYFOUR"
}

export interface ILocationInfo {
    location: officeLocations;
}

const LocationInfoRecord = Record({
    location: officeLocations.none
});

export class LocationInfo extends LocationInfoRecord implements ILocationInfo {
    public location: officeLocations;

    constructor(props?: ILocationInfo) {
        // props ? super(props) : super(); <-- in older project I use this line instead of if-else... but here it tell me I cannot invoke super multiple times...
        if (props) {super(props);}
        else {super();}
        this.location = props ? props.location : officeLocations.none; // <- In my older code I don't need this line, for some reason it give me an error that location is not instantiated if I don't put this line
    }

    public with(values: Partial<ILocationInfo>) {
      return this.merge(values);
    }
}

Jag förväntar mig att det fungerar utan problem... men Typescript ger mig inga problem och kompilerar, men när jag kör det kraschar det på "super()" och säger "Fel: Kan inte sätta på ett oföränderligt rekord".

**

UPPDATERING :

**

Idag, utan att ändra någonting, kommer det att ge mig detta fel:

Typen '(location: LocationInfo, action: IAction) => Map' kan inte tilldelas typen 'Reducer'. Typerna för parametrarna 'LocationInfo' och 'state' är inkompatibla. Typen 'Map | undefined' kan inte tilldelas typen 'LocationInfo'. Typen 'undefined' kan inte tilldelas typen 'LocationInfo'.

Och nu ger det mig detta fel även med min ursprungliga kod, den som förklarades med kommentarerna i koden.

detta fel ges när jag kallar på "combineReducers".

    const settingsReducer = combineReducers({
       location: locationReducer,
       other: otherReducer
    });

Svar #1

Record är en fabrik som producerar oföränderliga poster. Din kod försöker tilldela location på själva fabriken, inte på fabriksutgången.

Record-typer är mer begränsade än typiska JavaScript-klasser. De använder inte en klasskonstruktor, vilket också innebär att de inte kan använda klassens egenskaper (eftersom dessa tekniskt sett är en del av en konstruktor).

Även om Record-typer kan skapas syntaktiskt med JavaScript-klassformuläret, är den resulterande Record-funktionen faktiskt en fabrikfunktion, inte en klasskonstruktör.

TypeScript hanterar inte Immutable så bra. Båda vill ha explicita definitioner av strukturen, men de gör det på en annan nivå och på ett annat sätt, vilket gör att du skriver redundant kod.

Så location-egenskapen är bara för TS:s skull, den används egentligen inte. Vi bör inte försöka tilldela något till den, så säg bara till TS att den tilldelas magiskt:

public readonly location!: officeLocations

Och sedan ta bort this.location=props ? props.location : officeLocations.none;

Om du av någon anledning vill ändra ingången, gör det bara i konstruktorn och skicka allt till super:

constructor(values = {}, name) {
    values.location = values.location || officeLocations.none;
    super(values, name);
}

Här är en artikel med en beskrivning om hur man använder Immutable Records i TypeScript.