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

标签 javascript reactjs redux

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

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

密码必须至少是个字符

也许我没有使用 conditional rendering对的

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>

  );
 }

} 

最佳答案

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

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

请注意,将表单数据变量包装在状态内的 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,
        }
    })
}

关于javascript - 在 React 中验证表单的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54032554/

相关文章:

javascript - 在 JS 中选中时,我无法读取非默认单选按钮的值

javascript - 哪些操作触发 'Update layer tree' ?

javascript - 如何在 nextjs 的 Router.push() 中将对象作为参数传递并在其他组件中访问该对象

javascript - reactjs如何将数据从父组件传递到子组件?

javascript - 配置 firebase 项目域限制

javascript - 将对象作为 props 传递给 jsx。没有 {...obj}

javascript - 获取未禁用的输入值

javascript - React/Redux/Firebase createStore 配置

javascript - Redux thunk : wait for async function to dispatch

javascript - 无法调用 null 的方法 appendChild