[英]How to add a wrapper function for setState?
我在React中有一个用户注册表格,当用户名和密码文本字段的内容更改时,该表格会更新状态,例如:
<TextField onChange={e => this.updateUser(e)} />
updateUser(
evt: React.ChangeEvent<
HTMLTextAreaElement | HTMLInputElement | HTMLSelectElement
>
) {
const user = evt.target.value;
this.setState({ user });
}
但是,我想概括化updateUser()
和updatePassword()
函数,以便在向组件中添加更多字段时可以调用诸如updateField(e, "password")
类的东西updateField(e, "password")
而不是编写新函数来更新其中的每个字段。状态。
我已经试过了:
updateField(
evt: React.ChangeEvent<
HTMLTextAreaElement | HTMLInputElement | HTMLSelectElement
>,
field: string
) {
let updatedField = {};
updatedField[field] = evt.target.value; // error here
this.setState(updatedField);
}
我得到的错误是
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
No index signature with a parameter of type 'string' was found on type '{}'
我没有这样做
<TextField onChange={e => this.setState({user:e.target.value})} />
因为我的更新功能实际上比我在此处粘贴的功能要多
您的尝试即将结束。 您遇到的问题是string
的字段键太宽,可能是任何东西,因此类型检查器不会允许它用作状态键。 您想要的是将密钥约束为您状态的密钥。 假设您位于其中MyState
是状态类型参数的Component
中,则应做到这一点:
updateField<K extends keyof MyState>(
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement | HTMLSelectElement>,
field: K
) {
const { value } = event.target;
this.setState({
[field]: value
} as Pick<MyProps, K>);
}
您收到此错误是因为在声明时:
let updatedField = {};
对于类型,变量updatedField
具有一个空对象。 因此,当您尝试在其上设置属性时,TypeScript会告诉您您无法执行此操作,因为根据定义,空对象没有属性: 在类型“ {}”上未找到参数类型为“字符串”的索引签名
解决问题的一种简单方法是将您的代码更改为此:
updateField(
evt: React.ChangeEvent<
HTMLTextAreaElement | HTMLInputElement | HTMLSelectElement
>,
field: string
) {
this.setState({
[field]: evt.target.value
});
}
这将立即创建一个具有动态“计算”属性名称(您的字段)和事件传递的值的对象,然后将其提供给setState
。
编辑:正如亚伦·比尔(Aaron Beall)所说,TypeScript在这里显示错误,因为计算出的属性不是您所在州类型的一部分。 你应该参考他们的答案
您可以使用高阶函数来概括更新特定字段。 这是一个示例实现:
class ExampleForm extends React.Component { state = { name: '', password: '' } setStateFromValue = prop => ({target:{value}}) => { this.setState({[prop]: value}) } render () { return ( <form> <input onChange={this.setStateFromValue('name')} /> <input type="password" onChange={this.setStateFromValue('password')} /> <div> State: {JSON.stringify(this.state)} </div> </form> ) } } ReactDOM.render(<ExampleForm />, document.querySelector("#form"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="form"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.