reactjs - なぜ super() は不変のレコードに設定できないのですか?
私は本当にシンプルな新しいReduxストアの状態を設定しています。
以前作成したReduxストアを「クローン」して簡略化しました。最初は状態、リデューサー、セレクター、アクションをそれぞれ1つだけで試し、その後、ツリー(以前のプロジェクトのようなもの)を作ってみましたが、変わりませんでした。package.jsonを確認したところ、Redux、React、ReactRedux、TypeScript などのバージョンは同じでした。
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);
}
}
問題なく動作すると思っています…しかし、TypeScriptでは問題なくコンパイルされますが、実行すると「super()」でクラッシュし、「エラー: 不変レコードに設定できません」と表示されます。
**
更新:
**
今日、何も変更せずに、これが私にこのエラーを出します:
タイプ '(location: LocationInfo, action: IAction) => Map' はタイプ 'Reducer
' に割り当てられません。パラメータ 'LocationInfo' と 'state' のタイプが互換性がありません。タイプ 'Map | undefined' はタイプ 'LocationInfo' に割り当てられません。タイプ 'undefined' はタイプ 'LocationInfo' に割り当てられません。
そして今、元のコード、すなわちコードのコメントで説明されたものでも、このエラーが出ます。
このエラーは、私が「combineReducers」を呼び出したときに発生します。
const settingsReducer = combineReducers({
location: locationReducer,
other: otherReducer
});
回答 #1
Record は、不変のレコードを生成するファクトリーです。あなたのコードは、ファクトリー自体に location を代入しようとしており、ファクトリーの出力に対してではありません。
レコード型は、通常のJavaScriptクラスよりも制限が厳しいです。クラスコンストラクターを使用せず、それはつまりクラスプロパティも使用できないことを意味します(クラスプロパティは技術的にコンストラクターの一部だからです)。
Record Types は JavaScript のクラス形式で構文的に作成することができますが、結果として得られる Record 関数は実際にはクラスコンストラクタではなく、ファクトリ関数です。
TypeScriptはImmutableをうまく扱えません。両方とも構造の明示的な定義を望みますが、別のレベルと別の方法で行うため、冗長なコードを書くことになります。
なので location プロパティは TS のためだけのもので、実際には使用されません。そこに何かを割り当てようとすべきではないので、TS に魔法のように割り当てられると伝えるだけです:
public readonly location!: officeLocationsそして次に this.location=props ? props.location : officeLocations.none; を削除します
もし何らかの理由で入力を変更したい場合は、単にコンストラクタ内でそれを行い、すべてを super に渡してください:
constructor(values = {}, name) {
values.location = values.location || officeLocations.none;
super(values, name);
}
こちらは、TypeScriptでImmutable Recordsを使用する方法についての説明を含む記事です。
