Chuyển đến nội dung chính

React: Yup - Day 10

Yup là một thư viện JavaScript cho việc kiểm tra dữ liệu và xác thực dữ liệu trong ứng dụng React. Bạn có thể dùng Yup để thay thế cho propTypes

Cài đặt

npm install yup

Validation

Validate object đơn giản

Trong ví dụ này, chúng ta đang xác thực rằng giá trị phải là một chuỗi và không được phép rỗng.
import * as Yup from 'yup';

const schema = Yup.string().required();
const value = 'abc';

schema.validate(value).then(() => {
	console.log("Validate " + value + ' successfully');
});
Validate các giá trị phức tạp
import * as yup from 'yup';
//...

const schema = yup.object({
	name: yup.string().required(),
	age: yup.number().min(18).max(60),
});

const value = {
	name: 'John Doe',
	age: 16,
};


schema.validate(value).then(() => {
	console.log("Validate " + value + ' successfully');
}).catch((validationErrors) => {
validationErrors.errors.forEach((error: string) => {
	console.error(error);
});
});;
Validate các ràng buộc phức tạp
import * as yup from 'yup';
//...

const schema = yup.object({
	name: yup.string().required(),
	age: yup.number().min(18).max(60),
	email: yup.string().email(),
});

const value = {
	name: 'An Binh Trong',
	age: 30,
	email: 'anbinhtrong@',
};

schema.validate(value).then(() => {
		console.log("Validate " + value + ' successfully');
	}).catch((validationErrors) => {
validationErrors.errors.forEach((error: string) => {
		console.error(error);
	});
});
Kết quả:
email must be a valid email

Pass data từ Parent Component sang Child Component

Định nghĩa parent component (component cha) để truyền dữ liệu sang child component (component con).

import * as Yup from 'yup';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  const data = {
    name: 'John',
    age: 30,
  };

  const schema = Yup.object().shape({
    name: Yup.string().required('Name is required'),
    age: Yup.number().required('Age is required').positive().integer(),
  });

  return (
    <div>
      <h1>Parent Component</h1>
      <ChildComponent data={data} validationSchema={schema} />
    </div>
  );
};

export default ParentComponent;
Định nghĩa Child component
import React, { useState } from 'react';
import * as Yup from 'yup';
import { ValidationError } from 'yup';

interface Errors {
    [key: string]: string | undefined;
  }
  
interface FormData {
    name: string;
    age: number;
}

interface ChildComponentProps {
    data: FormData;
    validationSchema: Yup.ObjectSchema<FormData>;
}

const ChildComponent: React.FC<ChildComponentProps> = ({ data, validationSchema }) => {
    const [formData, setFormData] = useState(data);
    const [errors, setErrors] = useState<Errors>({});

    const handleInputChange = (e: any) => {
        const { name, value } = e.target;
        setFormData({
            ...formData,
            [name]: value,
        });
    };

    const handleSubmit = () => {
        validationSchema.validate(formData, { abortEarly: false })
            .then(() => {
                alert('Form submitted successfully');
                setErrors({});
            })
            .catch((validationErrors) => {
                const newErrors : Errors = {};
                validationErrors.inner.forEach((error: ValidationError) => {
                    const path = error.path || 'defaultPath'; //

                    newErrors[path] = error.message;
                });
                setErrors(newErrors);
            });
    };

    return (
        <div>
            <h2>Child Component</h2>
            <div>
                <label>Name:</label>
                <input
                    type="text"
                    name="name"
                    value={formData.name}
                    onChange={handleInputChange}
                />
                {errors.name && <div>{errors.name}</div>}
            </div>
            <div>
                <label>Age:</label>
                <input
                    type="number"
                    name="age"
                    value={formData.age}
                    onChange={handleInputChange}
                />
                {errors.age && <div>{errors.age}</div>}
            </div>
            <button onClick={handleSubmit}>Submit</button>
        </div>
    );
};

export default ChildComponent;

Chúng ta đã định nghĩa một parent component (ParentComponent) để truyền dữ liệu vào child component (ChildComponent) thông qua prop data. ChildComponent sử dụng local state để quản lý dữ liệu và xử lý sự kiện khi người dùng thay đổi giá trị của các trường input. Khi người dùng nhấn nút "Submit", chúng ta sử dụng Yup để kiểm tra dữ liệu dựa trên schema đã định nghĩa và hiển thị thông báo lỗi nếu có lỗi kiểm tra.

import * as Yup from 'yup'

Import toàn bộ thư viện yup và assign vào biến Yup

const { name, value } = e.target;

Destructuring Assignment là một cú pháp cho phép tách dữ liệu được lưu trữ bên trong (nested) Objects hoặc Arrays (tổng quát hơn là các iterable values) và gán chúng cho các biến riêng biệt. Trong trường hợp này name là tên của input và value là giá trị của input

setFormData({ ...formData, [name]: value })

hàm setFormData() để thay đổi giá trị của formData. Câu lệnh {...formData} sẽ tạo ra object dựa trên formData. Sử dụng ngoặc vuông [name] cho phép bạn sử dụng giá trị của biến name như một biến động để tạo tên thuộc tính trong đối tượng. Câu lệnh này dùng để update form-data thành giá trị mới

Kết luận

Hi vọng qua bài viết này, bạn sẽ nắm vững được cách sử dụng Yup để validate data. Trong phần tiếp theo, chúng ta sẽ tìm hiểu về react-axiosreact-hook-form

Nhận xét