首页 > 解决方案 > ReactJS:如何创建一个自我验证的输入字段?

问题描述

我有一个表单,其中一个字段需要非常具体的验证。我希望能够在其他表单中重用此字段,而不必一次又一次地重新实现验证方法。

我认为将输入字段提取到它自己的组件中,DomainInput会起作用:

<div id="domain-input-area" class={this.state.showDomain ? '' : 'base-remove'}>
     <DomainInput/>
</div>

DomainInput然后包含自己的所有验证逻辑

import { Component } from 'react';
//import '../../../login-box/login-box.styles.css'
import '../domain-input/domain-input.styles.css';

class DomainInput extends Component{

  constructor(){
    super();

    this.state = {
        domain:'',
        valid:false,
        error:''
    };
  }

  handleDomainInput = (e) => {

    let domain = e.target.value;
    let error = '';
    let valid = true;
  
    if(domain.indexOf('my.salesforce.com') === -1){
        error = `${this.state.domain} is not a valid salesforce domain`;
        valid = false;
        this.setState({error:error,valid:valid});
        
    }
  
    if(domain.indexOf('https://') != 0){
        error = `Please use https://`;
        valid = false;
        this.setState({error:error,valid:valid});;
        
    }

    if(valid){
        domain = domain.trim();
        let lastCharacter = domain.substr(domain.length-1);
        
        //remove last slash
        if(lastCharacter === '/'){
        domain = domain.substr(0,domain.length-1);
        }
    
        this.setState({domain:domain,valid:true});
    }
  }

  render(){
      return (
        <input type="text" placeholder="https://your-domain.my.salesforce.com" class={this.state.valid ? 'base-input valid' : 'base-input invalid'} id="domain-input"  onChange={this.handleDomainInput}/>
      )
  }
}

export default DomainInput

我的想法是,当DomainInput知道它的状态有效时,它会向父组件(表单)触发一个事件,让它知道它已经过验证。

但是我意识到由于单向数据流,这不是反应方式,而是onChange应该在父级中实现处理程序,正如我所说,我不想这样做,因为我希望能够DomainInput放入任何形式,并让它自己验证。

LWC等其他框架允许子组件向父组件发送自定义事件。在我的情况下,它会发送一个validated事件,这反过来会将父母的状态设置为validDomain:true

我该如何以反应的方式做到这一点?

标签: javascriptreactjsdom-events

解决方案


为了给您一个想法,您可以如何处理父级(管理状态)和子级(自定义输入字段),下面是示例代码:

文本字段.jsx

export const TextField = ({error, ...rest}) => {
  return (
    <div className="mb-6">
      <label htmlFor={rest.name} className="">
        {rest.label}
      </label>
      <input
        type="text"
        {...rest}
        className={ '' + (!!error ? ' border-red' : '')}
      />
      {error && <div className="...">{error}</div>}
    </div>
  )
}

父组件.jsx

 this.state = { email: '', error: '' }

 <TextField
        label="Email Address"
        name="email"
        value={this.state.email}
        placeholder="doge@example.com"
        onChange={handleChange}
        onBlur={handleBlur}
        error={state.error}
      />

现在验证您的输入并使用自定义的handleChangehandleBlur函数在父组件中相应地设置状态,如下所示:

handleChange = (event) => {
    let { name, value } = event.target
    // set state here and also validate
}

handleBlur = (event) => {
  let { name, value } = event.target
  // set state here and also validate
}

推荐阅读