Simple Form Validation in Reactjs

Đây là hướng dẫn từng bước làm thế nào để validate một form cơ bản trong React. Cài đặt package từ npm và tạo một ứng dụng mới:

$ npm install -g create-react-app 
$ create-react-app react-form-validation-demo

Bây giờ hãy chạy ứng dụng:

$ cd react-form-validation-demo/
$ npm start

Mở http://localhost:3000/ nơi ứng dụng mới của chúng ta đang chạy. Tiếp theo, chúng ta hãy thêm bootstrap để có thể dễ dàng tạo style cho form:

$ npm install react-bootstrap — save 
$ npm install [email protected] — save

Import Bootstrap CSS và Bootstrap them CSS trong file src/index.js:

import ‘bootstrap/dist/css/bootstrap.css’; 
import ‘bootstrap/dist/css/bootstrap-theme.css’;

Ok, bây giờ chúng ta hãy xây dựng ứng dụng demo. Hãy thêm một Form component. Trong src/App.js, hãy thay thế đoạn code mặc định bằng 1 Form component mà chúng ta sẽ xây dựng:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Form from './Form.js';
class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>React Form Validation Demo</h2>
        </div>
        <Form />
      </div>
    );
  }
}
export default App;

Bây giờ chúng ta hãy tạo Form component trong src/Form.js. Chúng ta sẽ tạo một mẫu đăng ký đơn giản với các trường nhập email và mật khẩu và một nút submit.

import React, { Component } from ‘react’;
import ‘./Form.css’;
class Form extends Component {
 render () {
   return (
     <form className=”demoForm”>
       <h2>Sign up</h2>
       <div className=”form-group”>
         <label htmlFor=”email”>Email address</label>
         <input type=”email” className=”form-control”
           name=”email” />
       </div>
       <div className=”form-group”>
         <label htmlFor=”password”>Password</label>
         <input type=”password” className=”form-control”
           name=”password” />
       </div>
       <button type=”submit” className=”btn btn-primary”>
          Sign up
       </button>
     </form>
   )
 }
}
export default Form;

classfor là những từ khóa trong JavaScript, vì vậy chúng ta sữ dụng classNamehtmlFor để thay thế nó. Bây giờ, hãy khởi tạo biến state trong contructor:

constructor (props) {
  super(props);
  this.state = {
    email: '',
    password: ''
  }
}

Chúng ta sẽ lấy những giá trị từ input trong form và đưa nó vào giá trị của state, cho mail:

<input type="email" required className="form-control" name="email"
placeholder="Email"
value={this.state.email}  />

và cho password:

<input type="password" className="form-control" name="password"
placeholder="Password"
value={this.state.password} />

Chúng ta cần một handler onChange cho các thẻ input:

onChange={this.handleUserInput}
handleUserInput = (e) => {
  const name = e.target.name;
  const value = e.target.value;
  this.setState({[name]: value});
}

Thêm vài thuộc tính khởi tạo cho state:

constructor (props) {
  super(props);
  this.state = {
    email: '',
    password: '',
    formErrors: {email: '', password: ''},
    emailValid: false,
    passwordValid: false,
    formValid: false
  }
}

Chúng ta đang thêm một thuộc tính gọi là formErrors, nó sẽ là một đối tượng với tên trường là các key và bất kỳ lỗi validate nào là các giá trị của chúng. Giá trị ban đầu cho mỗi key là chuỗi rỗng. Chúng ta cũng có 3 thuộc tính boolean là emailValid, passwordValidformValid, nó đc sữ dụng để kích hoạt hoặc vô hiệu nút submit, dựa trên kết quả validate.

<div className=”panel panel-default”>
 <FormErrors formErrors={this.state.formErrors} />
</div>

Chúng ta sẽ lưu nó trong src/FormErrors.js:

import React from ‘react’;
export const FormErrors = ({formErrors}) =>
  <div className='formErrors'>
    {Object.keys(formErrors).map((fieldName, i) => {
      if(formErrors[fieldName].length > 0){
        return (
          <p key={i}>{fieldName} {formErrors[fieldName]}</p>
        )        
      } else {
        return '';
      }
    })}
  </div>

Phương thức setState gọi một hàm callback như là một đối số thứ hai:

handleUserInput (e) {
  const name = e.target.name;
  const value = e.target.value;
  this.setState({[name]: value}, 
                () => { this.validateField(name, value) });
}

validateField(fieldName, value) {
  let fieldValidationErrors = this.state.formErrors;
  let emailValid = this.state.emailValid;
  let passwordValid = this.state.passwordValid;

  switch(fieldName) {
    case 'email':
      emailValid = value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
      fieldValidationErrors.email = emailValid ? '' : ' is invalid';
      break;
    case 'password':
      passwordValid = value.length >= 6;
      fieldValidationErrors.password = passwordValid ? '': ' is too short';
      break;
    default:
      break;
  }
  this.setState({formErrors: fieldValidationErrors,
                  emailValid: emailValid,
                  passwordValid: passwordValid
                }, this.validateForm);
}

validateForm() {
  this.setState({formValid: this.state.emailValid && this.state.passwordValid});
}

Chúng ta làm hai kiểm tra khác nhau cho các trường input. Đối với trường email, chúng ta kiểm tra nó đối với một chuổi regex để xem nó có phải là một email hay không. Đối với trường password, chúng ta kiểm tra độ dài tối thiểu là 6 ký tự. Khi trường bị unvalid, chúng ta sẽ set một error message cho nó và set tính hợp lệ của trường đó thành false. Sau đó chúng ta gọi setState để cập nhật formErrors và field validity, và truyền validateForm để set giá trị của formValid. Hãy đặt thuộc tính disable vào nút submit dựa trên giá trị của formValid.

<button type="submit" className="btn btn-primary"
  disabled={!this.state.formValid}>Sign up</button>

Như vậy, form validation của chúng ta đã hoạt động. Chúng ta có thể thêm một chút cải tiến bằng cách highligh các input fields khi chúng có lỗi.

<div className={`form-group
                 ${this.errorClass(this.state.formErrors.email)}`}>

errorClass là 1 phương thức chúng ta có thể định nghĩa nó:

errorClass(error) {
   return(error.length === 0 ? '' : 'has-error');
}

Bây giờ khi một trường có lỗi, nó có một đường viền màu đỏ xung quanh nó. Và đó là tất cả cho hướng dẫn này.


All Rights Reserved