typescriptで作成した単純な反応コンポーネントがあり、次のような奇妙なエラーが発生しました。ここに私のコードです。TypesScriptはプロパティが読み取り専用であると誤って認識しています
interface State {
value: string
}
class App extends React.Component<{}, State> {
constructor() {
super();
this.state = {
value: ''
}
}
changeHandler = (e: any) => {
let state = Object.assign({}, this.state);
state.value = e.target.value;
this.setState(state);
}
render() {
return (
<div className="App">
<input
type="text"
value={this.state.value}
name="value"
onChange={this.changeHandler} />
</div>
);
}
}
export default App;
これは私が得たエラーです。
エラーTS2540:定数または 読み取り専用プロパティなので、 'value'に割り当てることはできません。
このエラーは、これはおそらく、これが、状態を変更しないというルールを強制するタイスクリプトの方法だと思ってしまったのです。この理論をテストするために、私は以下を行った。
this.state.value = e.target.value
この場合、私は明らかに状態を明らかに突然変異させており、十分に私は同じエラーが発生しています。
私はこれに私のインターフェイスを変更する考えがありました。
interface State {
value: Ivalue
}
interface Ivalue {
value: string;
}
次に、このような新しいインターフェイスを使用するようにコンポーネントをリファクタリングしました。
class App extends React.Component<{}, State> {
constructor() {
super();
this.state = {
value: {
value: ''
}
}
}
changeHandler = (e: any) => {
let value = Object.assign({}, this.state.value);
value.value = e.target.value;
this.setState({value});
}
render() {
return (
<div className="App">
<input
type="text"
value={this.state.value.value}
name="value"
onChange={this.changeHandler} />
</div>
);
}
}
export default App;
これが十分にコンパイルされています。 私の質問は本当に2つの質問です。まず、なぜ私はObject.assign
を使用したコードの最初のスニペットのように、私の国のコピーにtypescriptが満足していないのですか? 次に、私の状態オブジェクトを1レベル下に入れ子にしてこの問題を解決するのはなぜですか?
これは機能します。 'state [e.target.name] = e.target.value'と同じように動作します。私はちょうどなぜオブジェクトを知りたいのですか。 –