Cha*_*man 7 javascript typescript reactjs
我有一个使用打字稿创建的简单反应组件,遇到以下奇怪的错误。这是我的代码。
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;
Run Code Online (Sandbox Code Playgroud)
这就是我得到的错误。
错误TS2540:因为它是常量或只读属性,所以无法分配给“值”。
这个错误让我想到也许这是打字稿执行不变异状态规则的方式。为了验证这一理论,我做了以下工作。
this.state.value = e.target.value
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我显然可以直接改变状态,并且可以肯定地得到相同的错误。
然后我想到了将界面更改为此的想法。
interface State {
value: Ivalue
}
interface Ivalue {
value: string;
}
Run Code Online (Sandbox Code Playgroud)
然后,我将组件重构为使用这种新接口。
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;
Run Code Online (Sandbox Code Playgroud)
当然可以编译了!我的问题确实是2个问题。首先,为什么打字稿不满意我的状态副本,就像我在使用的第一段代码中那样Object.assign?第二,为什么将我的状态对象嵌套更深一层来解决此问题?
如果 的内部实现(或 TypeScript 对其的理解)Object.assign是复制对象成员的描述符,而不仅仅是字段名称,那么它会复制readonly您的属性state.value,而不仅仅是您的state.value.
我不能保证这确实是正在发生的事情,因为这对我来说是新闻。但这实际上是个好消息,而不是坏消息。
您使用什么版本的东西?
setState另外,如果您打算在下一个主要版本中继续使用 的函数形式,您需要养成使用它的习惯。
| 归档时间: |
|
| 查看次数: |
3519 次 |
| 最近记录: |