在 React 中验证表单的最简单方法

新手上路,请多包涵

我很不确定如何在 React 中进行表单验证。

我想在当前页面上显示一条错误消息说。但是,密码验证被忽略,因此页面上不会显示错误。

密码必须至少为字符

也许我没有正确使用 条件渲染

SignUp.js (用于演示目的的片段)

 constructor(props){
 super(props);

 this.state ={
  errors: {},
}

handleSubmit(event) {
  event.preventDefault();

  const email = this.email.value;
  const password = this.password.value;

  if(password.length > 6){
    this.state.errors.password= "Password must be at least 6 characters";
  }
  const creds = {email, password}

  if(creds){
    this.props.signUp(creds);
    this.props.history.push('/');

  }
}

render() {
 return (
  <div className="container">
    <div className="row">
      <div className="col-md-6">
        <h1>Sign Up</h1>
        <form onSubmit={this.handleSubmit}>
          <div className="form-group">
            <label htmlFor="exampleInputEmail1">Email address</label>

            <input
              name="email"
              type="email"
              className="form-control"
              id="email"
              ref={(input) => this.email = input}
              aria-describedby="emailHelp"
              placeholder="Enter email" />
            <small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
          </div>
          <div className="form-group">
            <label htmlFor="exampleInputPassword1">Password</label>
            {this.password > 6 &&
               //display an error here
              <h2>{this.state.errors.password}</h2>
            }
            <input
              name="password"
              type="password"
              ref={(input) => this.password = input}
              value={this.state.password}
              className="form-control"
              id="password"
              placeholder="Password" />

          </div>

          <button type="submit" className="btn btn-primary">Submit</button>
        </form>
      </div>

    </div>
  </div>

  );
 }

}

原文由 Eric Thomas 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 785
2 个回答

您应该将表单数据存储在组件的状态中。例如,有 this.state.email 而不是 this.email 。当存储在组件状态中的数据更新时,将触发重新渲染。但是,不会为普通类变量的更新触发重新渲染。您还可以在设置 errors 时直接操纵状态。相反,您应该使用 setState 方法 文档

您没有在页面上看到错误的原因是由于表单更改导致您的页面未正确重新呈现。

请注意,将表单数据变量包装在 formData 组织状态内的对象中也是一个好主意。这有助于将表单数据与组件状态的其余部分分开(例如,将表单值与错误变量分开)并允许更轻松地传递表单数据,例如在表单提交期间。

以下是如何重新组织事物的示例:

 constructor(props){
 super(props);

 this.state = {
  formData: { // set up default form values
    email: "",
    password: "",
  },
  errors: {},
}

handleChange = event => {
  const { formData } = this.state;

  this.setState({
    formData: {
      ...formData, // leave other values unchanged
      [event.target.name]: event.target.value, // update the changed value
    }
  });
}

handleSubmit(event) {
  event.preventDefault();

  const { formData, errors } = this.state;
  const { email, password } = formData;

  if (password.length < 6) { // changed comparison to _less_ than
    this.setState({ // update errors using setState -- never directly modify a component's state
      errors: {
        ...errors,
        password: "Password must be at least 6 characters",
      }
    });
  }

  const creds = {email, password}

  if (creds.email && creds.password) { // objects are never falsey, so we need to check each field directly
    this.props.signUp(creds);
    this.props.history.push('/');

  }
}

render() {
 return (
  <div className="container">
    <div className="row">
      <div className="col-md-6">
        <h1>Sign Up</h1>
        <form onSubmit={this.handleSubmit}>
          <div className="form-group">
            <label htmlFor="exampleInputEmail1">Email address</label>

            <input
              name="email"
              type="email"
              className="form-control"
              id="email"
              value={ this.state.formData.email } {/* control component by storing value in state and updating state when the input changes */}
              onChange={ this.handleChange }
              aria-describedby="emailHelp"
              placeholder="Enter email" />
            <small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
          </div>
          <div className="form-group">
            <label htmlFor="exampleInputPassword1">Password</label>
            {this.state.errors.password &&
               //display an error here
              <h2>{this.state.errors.password}</h2>
            }
            <input
              name="password"
              type="password"
              value={ this.state.formData.password }
              onChange={ this.handleChange }
              className="form-control"
              id="password"
              placeholder="Password" />

          </div>

          <button type="submit" className="btn btn-primary">Submit</button>
        </form>
      </div>

    </div>
  </div>

  );
 }

}

注意:如果您的表单有复选框输入,显示的 handleChange 方法将无法按预期用于这些字段,因为应该使用复选框输入的 checked 属性而不是 value 属性。为简单起见,我只包括了非复选框的情况,但这里是 handleChange 的完整版本:

 handleChange = event => {
    const { formData } = this.state;
    const { name, type, value, checked } = event.target;
    this.setState({
        formData: {
            ...formData,
            [name]: type === "checkbox" ? checked : value,
        }
    })
}

原文由 Henry Woody 发布,翻译遵循 CC BY-SA 4.0 许可协议

我已经构建了自定义挂钩以便于表单验证。我认为这会让你的生活更容易形成。您可以利用您的 html 验证知识。

Github: https ://github.com/bluebill1049/react-hook-form

网站: http ://react-hook-form.now.sh

 import React from 'react'
import useForm from 'react-hook-form'

function App() {
  const { register, handleSubmit, errors } = useForm() // initialise the hook
  const onSubmit = (data) => { console.log(data) } // callback when validation pass

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} /> {/* register an input */}

      <input name="lastname" ref={register({ required: true })} /> {/* apply required validation */}
      {errors.lastname && 'Last name is required.'} {/* error message */}

      <input name="age" ref={register({ pattern: /\d+/ })} /> {/* apply a Refex validation */}
      {errors.age && 'Please enter number for age.'} {/* error message */}

      <input type="submit" />
    </form>
  )
}

原文由 Bill 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题