- vừa được xem lúc

React Hook Form - xử lý form dễ dàng hơn bao giờ hết

0 0 31

Người đăng: Nguyen Le Than

Theo Viblo Asia

Mở đầu

Hầu hết một Front-end Developer ai cũng trải qua việc xử lý form, nếu như không dùng thư viện thì việc này sẽ tốn rất nhiều thời gian để xử lý. Vì thế mình sẽ giới thiệu tới các bạn một thư viện giúp chúng ta tiết kiệm thời gian cho việc quản lý form, đó là React Hook Form.

Là một thư viện quản lý form tốt nhất hiện nay mà bạn nên dùng. Ở bài viết này mình sẽ demo code với ReactJS và TypeScript.

Tải xuống

npm install react-hook-form

Ví dụ cơ bản

Dưới đây là một ví dụ cơ bản của React Hook Form, các bạn hãy chú ý vào comment code để có thể hiểu về dòng code đó dùng để làm gì.

import React from "react";
import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit, formState: { errors } } = useForm({ criteriaMode: "all" }); return ( // Hàm handleSubmit sẽ validate trước khi gọi hàm onSubmit <form onSubmit={handleSubmit(onSubmit)}> // đăng kí input cho Hook vói tên example <input defaultValue="test" {...register("example")} /> // đăng kí thẻ input với React-Hook-Form với tên "exampleRequired" // validate là required <input {...register("exampleRequired", { required: true })} /> // xử lý lỗi bằng errrors {errors.exampleRequired && <span>This field is required</span>} <input type="submit" /> </form> );
} 

Khái niệm chính

useForm

useForm là một custom hook giúp quản lý form một cách dễ dàng.

Tham số truyền vào

Ví dụ:

 const { register, handleSubmit, formState: { errors } } = useForm({ mode: 'onSubmit', reValidateMode: 'onChange', defaultValues: {}, resolver: undefined, context: undefined, criteriaMode: "firstError", shouldFocusError: true, shouldUnregister: false, shouldUseNativeValidation: false, delayError: undefined
})

Một vài tham số thường dùng để truyền vào useForm:

mode : có các giá trị onChange | onBlur | onSubmit | onTouched | all . Dùng để cấu hình một chiến lược validate trước khi submit form.

  • onSubmit: sẽ thực hiện validate khi submit form, và những giá trị input không hợp lệ sẽ được lắng nghe sự thay đổi sau đó tiếp tục validate những giá trị input đó.
  • onChange: sẽ thực hiện validate khi mỗi khi onChange input, và nó dẫn đến re-render nhiều lần ( cần cân nhắc khi sử dụng ).
  • onBlur: sẽ thực hiện validate mỗi khi input có sự kiện blur.
  • onTouch: sẽ thực hiện validate cho lần blur đầu tiên, sau đó sẽ thực hiện validate cho mỗi lần change event.
  • all: sẽ thực hiện validate khi blur và change event.

defaultValues: thiết lập giá trị mặc định ( lần đầu ) cho form.

criteriaMode: có các giá trị firstError | all. Đối với firstError sẽ chỉ nhận được một lỗi đầu tiên, all sẽ nhận được tất cả lỗi.

resolver: hổ trợ validate đối với thirt-party ( yup ).

Tham số trả về

Register

Một trong những nội dung chính của React Hook Form, để đăng kí component của bạn với hook.

function App() { const { register, handleSubmit } = useForm(); const onSubmit = data => console.log(data); return ( <> <form onSubmit={handleSubmit(onSubmit)}> <input {...register("name")} /> <input type="submit" /> </form> </> );
}

Ví dụ:

<input {...register("test", { // validate required: true // bắt sự kiện onChange onChange: (e) => console.log(e) // bắt sự kiện onBlur onBlur: (e) => console.log(e) })}
/>

handleSubmit

handleSubmit sẽ thực hiện validate, nếu validate thành công sẽ gọi hàm onSubmit. ví dụ:

 <form onSubmit={handleSubmit(onSubmit)}> // các thẻ input khác ... <input type="submit" /> </form> );

formState

import React from "react";
import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit, formState: { errors, isDirty, isSubmitting, isSubmitted, submitCount, isValid, isValidating }, } = useForm(); const onSubmit = (data: FormInputs) => console.log(data); return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("test")} /> <input type="submit" /> </form> );
}

Các giá trị của formState:

  • errors trả về một object chứa lỗi.
  • isDirty so sánh với defaultValue trả về true nếu value hiện tại khác với defaultValue ( dùng để show pop-up khi user chỉnh sửa nhưng chưa submit ).
  • isSubmitting trả về true khi form đang submit.
  • isSubmitted trả về true khi form submit xong.
  • submitCount trả về thời gian ( dạng number ) submit form .
  • isValid trả về true nếu không có bất kì lỗi nào, false khi có lỗi.
  • isValidating trả về true nếu đang validate.

watch

watch sẽ lắng nghe sự thay đổi của ô input ( giống như sự kiện onChange ). watchShowAge sẽ tự động trigger nếu có sự thay đổi.

import React from "react";
import { useForm } from "react-hook-form"; function App() { const { register, watch, formState: { errors }, handleSubmit } = useForm(); const watchShowAge = watch("showAge", false); // đăng kí watch cho field showAge, truyền giá trị mặc định bằng đối số thứ 2 const watchAllFields = watch(); // nếu không truyền tham số, watch sẽ lắng nghe và trả về tất cả fields const onSubmit = data => console.log(data); return ( <> <form onSubmit={handleSubmit(onSubmit)}> <input type="checkbox" {...register("showAge")} /> <input type="submit" /> </form> </> );
}

reset

Reset dùng để đặt lại giá trị mặc định cho Form ( thường dùng để sau khi call API chúng ta sẽ đặt lại giá trị mặc định để lắng nghe sự thay đổi của isDirty ).

import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit, reset } = useForm(); const onSubmit = (data) => { // call API const data = fetchListUser(); reset(data); // đặt lại giá trị mặc định cho Form }; return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("firstName", { required: true })} /> <input {...register("lastName")} /> <input type="submit" /> </form> );
}

setError

setError dùng để set lỗi cho một element.

import { useForm } from "react-hook-form"; const App = () => { const { register, handleSubmit, setError, formState: { errors } } = useForm(); const onSubmit = data => { console.log(data) }; return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register('firstName'}/> {errors.firstName && <p>{errors.firstName.message}</p>} <button onClick={() => setError("firstName",'Message Error')}} > Set Error </button> </form> );
};

clearError

Đã có setError thì phải có clearError.

import { useForm } from "react-hook-form"; const App = () => { const { register, handleSubmit, clearError, formState: { errors } } = useForm(); const onSubmit = data => { console.log(data) }; return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register('firstName'}/> {errors.firstName && <p>{errors.firstName.message}</p>} <button onClick={() => clearError("firstName")}} > Clear Error </button> </form> );
};

setValue

Đây là function cho phép bạn set value cho một element.

import { useForm } from "react-hook-form"; const App = () => { const { register, handleSubmit, setValue, formState: { errors } } = useForm(); const onSubmit = data => { console.log(data) }; return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register('firstName'}/> {errors.firstName && <p>{errors.firstName.message}</p>} <button onClick={() => setValue("test",'')}} > // set value của ô input thành '' ( rỗng ) Clear Value </button> </form> );
};

setFocus

setFocus được dùng để set focus cho một element.

export default function App() { const { register, handleSubmit, setFocus } = useForm(); const onSubmit = (data) => console.log(data); useEffect(() => { setFocus("firstName"); }, []); return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("firstName")} placeholder="First Name" /> <input type="submit" /> </form> );
}

getValues

Thường được dùng để lấy value hiện tại trên element.

import React from "react";
import { useForm } from "react-hook-form"; export default function App() { const { register, getValues } = useForm(); return ( <form> <input {...register("test")} /> <input {...register("test1")} /> <button type="button" onClick={() => { const values = getValues(); // { test: "test-input", test1: "test1-input" } const singleValue = getValues("test"); // "test-input" const multipleValues = getValues(["test", "test1"]); // ["test-input", "test1-input"] }} > Get Values </button> </form> );
}

trigger Đây là trường hợp bạn muốn re-validate một cách thủ công hãy dùng trigger(). ví dụ:

trigger("lastName"); // chỉ trigger lastName trigger(["firstName", "lastName"]); // trigger lastName firstName trigger(); // trigger tất cả

Validation và xử lý lỗi như thế nào ?

Validate, đây là phần khá quan trọng trong React Hook Form nó giúp các bạn thực hiện việc validate dễ dàng hơn. React Hook Form hổ trợ một số case validate như sau:

  • required
  • min
  • max
  • minLength
  • maxLength
  • pattern
  • validate

Chúng ta cùng xem ví dụ dưới đây:

import { ErrorMessage } from "@hookform/error-message";
import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit, formState: { errors } } = useForm({ criteriaMode: "all" }); const onSubmit = (data) => console.log(data); return ( <form onSubmit={handleSubmit(onSubmit)}> <h1>ErrorMessage</h1> <input {...register("multipleErrorInput", { // xử lý lỗi khi bỏ trống required: "This input is required.", // xử lý lỗi khi nhập khác giá trị là số pattern: { value: /\d+/, message: "This input is number only." }, // xử lý lỗi khi nhập nhiều hơn 10 kí tự minLength: { value: 11, message: "This input must exceed 10 characters" } })} /> // ErrorMessage được import từ thư viện <ErrorMessage // nhận vào props errors ( errors lấy từ formState ở trên ) nó sẽ trigger khi phát hiện lỗi khác. errors={errors} // name tương ứng với name input đã đăng kí với hook name="multipleErrorInput" // sẽ render ra giao diện khi có error, ở đây là thẻ p render={({ messages }) => { return messages.map((message,index) => ( <p key={index}>{message}</p> )) : null; }} /> <input type="submit" /> </form> );
}

Bạn có thể tham khảo thêm tại đây

Validate với yup

React-Hook-Form hổ trợ validate với yup, các bạn cần phải hiểu rõ về yup để tạo được schema Ví dụ:

import { useForm } from "react-hook-form";
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from "yup"; // tạo schema để validate
const schema = yup.object({ firstName: yup.string().required(), age: yup.number().positive().integer().required(),
}).required(); export default function App() { const { register, handleSubmit, formState:{ errors } } = useForm({ // resolver dùng để validate với yup resolver: yupResolver(schema) }); const onSubmit = data => console.log(data); return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("firstName")} /> <p>{errors.firstName?.message}</p> <input {...register("age")} /> <p>{errors.age?.message}</p> <input type="submit" /> </form> );
}

Controller

Khi dùng thư viện bên ngoài như MaterialUI, Andt, ReactSelect, ReactDapicker chúng ta sẽ sử dụng Controller để xử lý form.

control chứa các phương thức để đăng kí component với hook Ví dụ:

function App() { const { handleSubmit, control } = useForm(); return ( <form onSubmit={handleSubmit(data => console.log(data))}> <Controller control={control} name="ReactDatepicker" render={({ field: { onChange, onBlur, value, ref } }) => ( <ReactDatePicker onChange={onChange} onBlur={onBlur} selected={value} /> )} /> <input type="submit" /> </form> );
}

Kết thúc

Đây là những khái niệm chính của React-Hook-Form, có thể giúp bạn quản lý form một cách dễ dàng. Cảm ơn đã đọc bài viết 😄 😄

Tài liệu tham khảo

https://react-hook-form.com/

Bình luận

Bài viết tương tự

- vừa được xem lúc

React Hook Form with yup resolver

Trong lúc làm dự án, chắc hẳn các bạn cũng nhiều lần bối rối trong việc xử lý các form như thế nào, quản lý nó ra sao cho hợp lí. Theo thông thường bạn phải quản lý từng state của từng field input điề

0 0 158

- vừa được xem lúc

Làm thế nào để Build React Forms đơn giản với react-hook-form?

React-hook-form là một thư viện form tiện ích, dễ sử dụng và giúp validation form đơn giản hơn. Cài đặt. Với npm:. npm i react-hook-form.

0 0 64

- vừa được xem lúc

Những điều cần lưu ý và sử dụng Hook trong React (Phần 5)

V. Sử dụng useRef như thế nào cho đúng.

0 0 127

- vừa được xem lúc

7 Cách viết code React "clean" hơn

Mở đầu. Là nhà phát triển React, tất cả chúng ta đều muốn viết code sạch hơn, đơn giản hơn và dễ đọc hơn. 1. Sử dụng JSX shorthands.

0 0 188

- vừa được xem lúc

Create app covid-19 use Reactjs

Chào các bạn hôm nay mình sẽ chia sẻ với các bạn một app covid-19, để mọi người cùng tham khảo, tính năng của App này chỉ đơn giản là show số liệu về dịch Covid của các nước trên thế giới như: Số ngườ

0 0 39

- vừa được xem lúc

ReactJS Custom Hooks

ReactJS cung cấp rất nhiều cho bạn các hook mà bạn có thể sử dụng hằng ngày vào project của mình. Nhưng bên cạnh đó bạn có thể tự tạo ra các hook của riêng bạn để sử dụng, làm cho việc tối ưu hóa code

0 0 65