Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何为setState添加包装函数?_Javascript_Reactjs_Typescript - Fatal编程技术网

Javascript 如何为setState添加包装函数?

Javascript 如何为setState添加包装函数?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我在React中有一个用户注册表单,当用户名和密码文本字段的内容更改时更新状态,例如: this.updateUser(e)}/> updateUser( evt:React.ChangeEvent< HTMLTextAreaElement | HTMLInputElement | HTMLSelect Element > ) { const user=evt.target.value; this.setState({user}); } 但是,我想概括一下updateUser()和updat

我在React中有一个用户注册表单,当用户名和密码文本字段的内容更改时更新状态,例如:

this.updateUser(e)}/>
updateUser(
evt:React.ChangeEvent<
HTMLTextAreaElement | HTMLInputElement | HTMLSelect Element
>
) {
const user=evt.target.value;
this.setState({user});
}
但是,我想概括一下
updateUser()
updatePassword()
函数,这样当我向组件添加更多字段时,我可以调用类似
updateField(e,“password”)
的函数,而不是编写一个新函数来更新状态中的每个字段

我试过这个:

updateField(
evt:React.ChangeEvent<
HTMLTextAreaElement | HTMLInputElement | HTMLSelect Element
>,
字段:字符串
) {
让updatedField={};
updatedField[field]=evt.target.value;//此处出错
this.setState(updated字段);
}
我得到的错误是

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 '{}'
我不会这么做的

this.setState({user:e.target.value})}/>

因为我的更新函数实际上比我粘贴在这里做的要多一些

您会遇到此错误,因为当您声明此错误时:

let updatedField = {};
变量
updatedField
的类型为空对象。因此,当您尝试在其上设置属性时,TypeScript告诉您不能这样做,因为根据定义,空对象没有属性:在类型{}上找不到具有“string”类型参数的索引签名

解决此问题的简单方法是将代码更改为:

updateField(
  evt: React.ChangeEvent<
    HTMLTextAreaElement | HTMLInputElement | HTMLSelectElement
  >,
  field: string
) {
  this.setState({
    [field]: evt.target.value
  });
}
updateField(
evt:React.ChangeEvent<
HTMLTextAreaElement | HTMLInputElement | HTMLSelect Element
>,
字段:字符串
) {
这是我的国家({
[字段]:evt.target.value
});
}
这将立即创建一个具有动态名称(您的字段)和事件传递的值的对象,然后将该值提供给
setState


编辑:如上所述,TypeScript在此处显示错误,因为计算属性不是您所在州类型的一部分。您应该参考他们的答案

您可以使用高阶函数来概括更新特定字段。下面是一个示例实现:

class ExampleForm扩展了React.Component{
状态={
名称:“”,
密码:“”
}
setStateFromValue=prop=>({target:{value}})=>{
this.setState({[prop]:value})
}
渲染(){
返回(
状态:{JSON.stringify(this.State)}
)
}
}
ReactDOM.render(,document.querySelector(“表单”))

您的尝试已接近成功。您遇到的问题是
string
的字段键太宽,它可能是任何内容,因此类型检查器不允许将其用作状态键。您想要的是将该键约束为您的状态的键。假设您在一个
组件中,其中
MyState
是状态类型参数,这应该可以实现以下功能:

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>);
}
updateField(
事件:React.ChangeEvent,
字段:K
) {
const{value}=event.target;
这是我的国家({
[字段]:值
}作为选择);
}

setState
不会接受这个论点,虽然你完全正确,但我不记得TypeScript有多严格。我应该包括泛型类型。