Sud*_*hra 4 javascript reactjs react-jsx
我有在它超过10个字段一个反应基形式,我的状态对那些10个form字段(控制部件).
这些input字段中的大多数text仅为类型,但稍后将添加其他类型字段.
问题是我需要为它们编写10个更改处理程序以正确设置状态,然后在构造函数中为每个处理程序添加方法绑定.
我很反应,可能不了解正确的方法和技术.
请指导我如何改进我当前的代码结构,避免编写样板和重复的错误代码.
我目前的注册组件如下 -
export default class Register extends Component {
constructor(props){
super(props);
this.state = {
regName : '',
regAdd1 : '',
regAdd2 : '',
regState : '',
regZipCode : '',
regCity : '',
regPhone : ''
};
// add bindings .... ugh..
this.changeRegAdd1 = this.changeRegAdd1.bind(this);
this.changeRegAdd2 = this.changeRegAdd2.bind(this);
//Similary binding for other handlers...
}
// add individual field change handlers ... ugh...
changeRegName(e) {
this.setState({regName:e.target.value});
}
changeRegAdd1(e) {
this.setState({regAdd1:e.target.value});
}
changeRegAdd2(e) {
this.setState({regAdd2:e.target.value});
}
changeRegState(e) {
this.setState({regState:e.target.value});
}
// Similary for other change handler ....
handleSubmit(e) {
e.preventDefault();
// validate then do other stuff
}
render(){
let registrationComp = (
<div className="row">
<div className="col-md-12">
<h3>Registration Form</h3>
<fieldset>
<div className="form-group">
<div className="col-xs-12">
<label htmlFor="regName">Name</label>
<input type="text" placeholder="Name"
onChange={this.changeregName} value = {this.state.regName} className="form-control" required autofocus/>
</div>
</div>
<div className="form-group">
<div className="col-xs-12">
<label htmlFor="regAdd1">Address Line1</label>
<input
type = "text"
placeholder = "Address Line1"
onChange = {this.changeregAdd1}
value = {this.state.regAdd1}
className = "form-control"
required
autofocus
/>
<input
type = "text"
placeholder = "Address Line2"
onChange = {this.changeregAdd2}
value = {this.state.regAdd2}
className = "form-control"
required
autofocus
/>
</div>
</div>
<div className="form-group">
<div className="col-xs-6">
<label htmlFor="regState">State</label>
<input
type = "text"
placeholder = "State"
onChange = {this.changeregState}
value = {this.state.regState}
className = "form-control"
required
autofocus
/>
</div>
<div className="col-xs-6">
<label htmlFor="regZipCode">Zip Code</label>
<input
type = "text"
placeholder = "Zip Code"
onChange = {this.changeregZipCode}
value = {this.state.regZipCode}
className = "form-control"
required
autofocus
/>
</div>
</div>
<div className="form-group">
<div className="col-xs-12">
<label htmlFor="regCity">City</label>
<input
type = "text"
placeholder = "City"
title = "City"
onChange = {this.changeregCity}
value = {this.state.regCity}
className = "form-control"
required
autofocus
/>
</div>
</div>
{/* other form fields */}
</fieldset>
</div>
</div>
);
return registrationComp;
}
}
Run Code Online (Sandbox Code Playgroud)
可能有其他很多方法可以做到,我可能不知道.
但我更喜欢在某种常见字段的常用方法中进行变更处理,例如 <input type of text />
这是一个示例输入字段 -
<input
onChange = {this.onChange}
value = {this.state.firstName}
type = "text"
name = {"firstName"}
/>
Run Code Online (Sandbox Code Playgroud)
我保持状态的字段名称和输入的"名称"属性相同.之后,我为所有这些字段编写了一个通用的更改处理程序.
需要在变更处理程序中只写一行.
onChange(e) {
this.setState({[e.target.name]: e.target.value});
}
Run Code Online (Sandbox Code Playgroud)
我使用es6的动态属性设置从字符串作为属性名称
{ ["propName] : propValue }.
Run Code Online (Sandbox Code Playgroud)
为了避免为反应组件中的方法编写手动绑定,您可以遵循以下两种方法 -
在组件中创建这样的方法.
_bind(...methods) {
methods.forEach( (method) => this[method] = this[method].bind(this) );
}
Run Code Online (Sandbox Code Playgroud)
用于_bind绑定您的方法.
constructor(props){
super(props);
this.state = {
regName : '',
regAdd1 : '',
regAdd2 : '',
regState : '',
regZipCode : '',
regCity : '',
regPhone : ''
};
// add bindings .... ugh..
//this.changeRegAdd1 = this.changeRegAdd1.bind(this);
//this.changeRegAdd2 = this.changeRegAdd2.bind(this);
//Similary binding for other handlers...
this._bind(
'changeRegName',
'changeReg1' , 'changeRegAdd2'
// and so on.
);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
添加验证 -
设置一个状态以指示表单有错误.可以在状态的错误对象中找到特定的错误详细信息.
validateInput() {
let errors = {};
Object.keys(this.state)
.forEach((stateKey) => {
isEmpty(this.state[stateKey]) ? (errors[stateKey] = `*required` ) : null;
});
return {
errors,
isValid : isEmptyObj(errors)
};
}
isFormValid() {
const { errors, isValid } = this.validateInput();
if (!isValid) {
this.setState({ errors});
}
return isValid;
}
onSubmit(e) {
e.preventDefault();
this.setState({errors : {}});
if (this.isFormValid()) {
// Perform form submission
}
}
Run Code Online (Sandbox Code Playgroud)我习惯了实用方法calld isEmpty, isEmptyObj. 它们只检查对象是null还是未定义或field是否为空.
我希望这有帮助.