如何避免以反应形式添加现场更换处理方法和其他样板?

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)

Wit*_*ult 5

可能有其他很多方法可以做到,我可能不知道.

但我更喜欢在某种常见字段的常用方法中进行变更处理,例如 <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)

为了避免为反应组件中的方法编写手动绑定,您可以遵循以下两种方法 -

  1. 使用es6箭头功能
  2. 一个黑客(我不知道这种方法是快还是慢但它有效:))

在组件中创建这样的方法.

_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)

编辑:

添加验证 -

  1. 编写一个可以迭代状态键并检查状态是否为空的方法.
  2. 如果任何输入字段为空,请收集有关该输入的详细信息并标记所需.
  3. 设置一个状态以指示表单有错误.可以在状态的错误对象中找到特定的错误详细信息.

    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是否为空.

我希望这有帮助.