Yup 및 React Hook 양식으로 간편하게 양식 유효성 검사
24557 단어 javascriptreactwebdev
비디오 버전
Video version youtube
최종 데모

시작하기 위해 새로운 반응 프로젝트를 생성하고 tailwind css를 설정했습니다.
반응 프로젝트에 tailwind css를 추가하려면 이 가이드tailwindcss-react를 따르십시오.
이것이 내가 현재 가지고 있는 것입니다:
App.js
function App() {
return <div className="w-screen h-screen bg-gradient-to-r from-blue-900 to-purple-900 grid place-content-center">
</div>;
}
export default App;
다음으로 양식 구성 요소를 저장할 구성 요소 폴더를 만들어 보겠습니다.
src/components/Form/Form.jsx
이 시점에서 양식 구성 요소를 만들고 다양한 양식 입력을 갖게 됩니다.
const textInputClassName =
"bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500";
const Form = () => {
return (
<div className="md:w-[500px] shadow-sm shadow-white bg-white w-[320px] mx-auto px-7 py-4 rounded-xl">
<form className="w-full">
<div className="mb-6">
<label
htmlFor="email"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Your email
</label>
<input
type="email"
id="email"
className={textInputClassName}
placeholder="[email protected]"
/>
</div>
<div className="mb-6">
<label
htmlFor="password"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Your password
</label>
<input type="password" id="password" className={textInputClassName} />
</div>
<div className="mb-6">
<label
htmlFor="confirmPassword"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Confirm Password
</label>
<input
type="password"
id="confirmPassword"
className={textInputClassName}
/>
</div>
<div className="mb-6">
<label
htmlFor="accountType"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
>
Select an option
</label>
<select
id="accountType"
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
>
<option value="">Account Type</option>
<option value="personal">Personal</option>
<option value="commercial">Commercial</option>
</select>
</div>
<div className="flex justify-between mb-6">
<div className="flex">
<div className="flex items-center h-5">
<input
id="remember"
type="checkbox"
value=""
className="w-4 h-4 bg-gray-50 rounded border border-gray-300 focus:ring-3 focus:ring-blue-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-blue-600 dark:ring-offset-gray-800"
/>
</div>
<label
htmlFor="remember"
className="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Remember me
</label>
</div>
<div>
<label
htmlFor="default-toggle"
className="inline-flex relative items-center cursor-pointer"
>
<input
type="checkbox"
value=""
id="default-toggle"
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
<span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">
Toggle me
</span>
</label>
</div>
</div>
<button
type="submit"
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
>
Submit
</button>
</form>
</div>
);
};
export default Form;
이제 양식 구성 요소 JSX를 완료했습니다. 계속해서 양식을 App.js에 추가하겠습니다.
import Form from "./components/Form/Form";
function App() {
return (
<div className="w-screen h-screen bg-gradient-to-r from-blue-900 to-purple-900 grid place-content-center">
<Form />
</div>
);
}
export default App;
App.js는 이제 다음과 같이 표시되어 이 결과를 제공합니다.

이제 양식 디자인이 완료되었으므로 유효성 검사를 추가해 보겠습니다. 다음 패키지를 설치해야 합니다.
npm install -D yup @hookform/resolvers react-hook-form
또는 원사를 사용하는 경우yarn add -D yup @hookform/resolvers react-hook-form
Yup은 값 구문 분석 및 유효성 검사를 위한 스키마 빌더가 될 것입니다.
React-hook-form은 양식 입력의 유효성을 검사하는 데 도움이 됩니다.
@hookform/resolvers는 yup과 react-hook-form을 멋지게 통합하는 데 사용됩니다.
방금 Form 구성 요소에 설치한 패키지를 가져오겠습니다.
/components/Form/Form.jsx
import { useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
ValidationSchema 구축을 시작하기 전에 html 양식에 name 속성을 추가해야 합니다. 이는 yup 및 react-hook-form이 다양한 입력을 추적하는 데 중요하기 때문입니다.
<form className="w-full">
<div className="mb-6">
<label
htmlFor="email"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Your email
</label>
<input
type="email"
name="email"
id="email"
className={textInputClassName}
placeholder="[email protected]"
/>
</div>
<div className="mb-6">
<label
htmlFor="password"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Your password
</label>
<input type="password" id="password" className={textInputClassName} />
</div>
<div className="mb-6">
<label
htmlFor="confirmPassword"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Confirm Password
</label>
<input
name="password"
type="password"
id="confirmPassword"
className={textInputClassName}
/>
</div>
<div className="mb-6">
<label
htmlFor="accountType"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
>
Select an option
</label>
<select
name="accountType"
id="accountType"
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
>
<option value="">Account Type</option>
<option value="personal">Personal</option>
<option value="commercial">Commercial</option>
</select>
</div>
<div className="flex justify-between mb-6">
<div className="flex">
<div className="flex items-center h-5">
<input
id="remember"
name="remember"
type="checkbox"
value=""
className="w-4 h-4 bg-gray-50 rounded border border-gray-300 focus:ring-3 focus:ring-blue-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-blue-600 dark:ring-offset-gray-800"
/>
</div>
<label
htmlFor="remember"
className="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Remember me
</label>
</div>
<div>
<label
htmlFor="toggle"
className="inline-flex relative items-center cursor-pointer"
>
<input
type="checkbox"
name="toggle"
value=""
id="toggle"
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
<span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">
Accept
</span>
</label>
</div>
</div>
<button
type="submit"
className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
>
Submit
</button>
</form>
유효성 검사 스키마를 빌드하겠습니다. 이를 위해 formSchema.js 파일 내부에 새 스키마 폴더를 생성하겠습니다.
다음과 같이 formSchema를 작성해 보겠습니다.
import * as yup from "yup";
export const registerSchema = yup.object().shape({
email: yup
.string("email should be a string")
.email("please provide a valid email address")
.required("email address is required"),
});
이메일 키는 jsx의 이름 속성과 일치해야 합니다.
Form.js에서
import { registerSchema } from "../../schema/formSchema";
// Saving space
const Form = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(registerSchema),
});
// Saving space
}
register는 입력을 react-hook-form으로 등록하는 데 사용됩니다.
handleSubmit은 양식 onSubmit에 추가되어야 하며 양식을 제출할 때 양식 유효성 검사를 사용하는 데 도움이 됩니다.
formState는 양식 상태(이 경우 오류 상태)를 추적하는 데 도움이 됩니다.
이것을 이메일 입력에 추가하겠습니다.
{...register("email")}
및 오류 jsx를 기록해 두십시오.<label
htmlFor="email"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Your email
</label>
<input
{...register("email")}
type="email"
name="email"
id="email"
className={textInputClassName}
placeholder="[email protected]"
/>
{errors.email ? (
<span className="text-red-900">{errors.email.message}</span>
) : (
<></>
)}
양식 제출 핸들러에 다음을 추가해 보겠습니다.
<form onSubmit={handleSubmit(formSubmitHandler)} className="w-full">
// saving space
</from
유효성 검사가 통과되면 양식 데이터를 자동으로 전달하는 사용자 지정 함수인 formSubmitHandler를 전달했음을 알 수 있습니다.
const formSubmitHandler = (data) => {
console.log(data);
};
이것으로 양식 유효성 검사가 이미 작동하고 있으며 다음과 같은 결과가 있어야 합니다.

비밀번호 확인 및 비밀번호 확인
스키마 파일에 다음을 추가해 보겠습니다.
export const registerSchema = yup.object().shape({
email: yup
.string("email should be a string")
.email("please provide a valid email address")
.required("email address is required"),
password: yup
.string("password should be a string")
.min(5, "password should have a minimum length of 5")
.max(12, "password should have a maximum length of 12")
.required("password is required"),
confirmPassword: yup
.string("password should be a string")
.oneOf([yup.ref("password")])
.required("confirm password is required"),
});
Form.js로 돌아가서 암호를 업데이트하고 이것에 대한 암호를 확인하겠습니다.
<div className="mb-6">
<label
htmlFor="password"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Your password
</label>
<input
{...register("password")}
type="password"
name="password"
id="password"
className={textInputClassName}
/>
{errors.password ? (
<span className="text-red-900">{errors.password.message}</span>
) : (
<></>
)}
</div>
<div className="mb-6">
<label
htmlFor="confirmPassword"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Confirm Password
</label>
<input
{...register("confirmPassword")}
name="confirmPassword"
type="password"
id="confirmPassword"
className={textInputClassName}
/>
{errors.confirmPassword ? (
<span className="text-red-900">{errors.confirmPassword.message}</span>
) : (
<></>
)}
</div>
이것은 우리에게 이 결과를 줍니다

유효성 검사 선택
스키마 파일을 다음과 같이 업데이트하겠습니다.
import * as yup from "yup";
export const registerSchema = yup.object().shape({
email: yup
.string("email should be a string")
.email("please provide a valid email address")
.required("email address is required"),
password: yup
.string("password should be a string")
.min(5, "password should have a minimum length of 5")
.max(12, "password should have a maximum length of 12")
.required("password is required"),
confirmPassword: yup
.string("password should be a string")
.oneOf([yup.ref("password")])
.required("confirm password is required"),
accountType: yup
.string("account type should be a string")
.oneOf(["personal", "commercial"])
.required("account type is required"),
});
이제 select jsx도 업데이트하겠습니다.
<div className="mb-6">
<label
htmlFor="accountType"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400"
>
Select an option
</label>
<select
{...register("accountType")}
name="accountType"
id="accountType"
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
>
<option value="">Account Type</option>
<option value="personal">Personal</option>
<option value="commercial">Commercial</option>
</select>{" "}
{errors.accountType ? (
<span className="text-red-900">{errors.accountType.message}</span>
) : (
<></>
)}
</div>
이제 우리는 이것을

마지막으로 토글과 체크박스의 유효성을 검사해 보겠습니다.
스키마 파일을 업데이트하여 시작합니다.
import * as yup from "yup";
export const registerSchema = yup.object().shape({
email: yup
.string("email should be a string")
.email("please provide a valid email address")
.required("email address is required"),
password: yup
.string("password should be a string")
.min(5, "password should have a minimum length of 5")
.max(12, "password should have a maximum length of 12")
.required("password is required"),
confirmPassword: yup
.string("password should be a string")
.oneOf([yup.ref("password")])
.required("confirm password is required"),
accountType: yup
.string("account type should be a string")
.oneOf(["personal", "commercial"])
.required("account type is required"),
remember: yup.boolean().oneOf([true], "Please tick checkbox"),
toggle: yup.boolean().oneOf([true], "Please toggle accept"),
});
그런 다음 from 체크박스를 업데이트하고 jsx를 토글합니다.
<div className="flex justify-between mb-6">
<div>
<div className="flex">
<div className="flex items-center h-5">
<input
{...register("remember")}
id="remember"
name="remember"
type="checkbox"
value=""
className="w-4 h-4 bg-gray-50 rounded border border-gray-300 focus:ring-3 focus:ring-blue-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-blue-600 dark:ring-offset-gray-800"
/>
</div>
<label
htmlFor="remember"
className="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"
>
Remember me
</label>
</div>
{errors.remember ? (
<span className="text-red-900">{errors.remember.message}</span>
) : (
<></>
)}
</div>
<div>
<div>
<label
htmlFor="toggle"
className="inline-flex relative items-center cursor-pointer"
>
<input
{...register("toggle")}
type="checkbox"
name="toggle"
value=""
id="toggle"
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
<span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">
Accept
</span>
</label>
</div>
{errors.toggle ? (
<span className="text-red-900">{errors.toggle.message}</span>
) : (
<></>
)}
</div>
</div>
이것으로 우와, 우리는 이 결과로 끝났습니다

팔로우해 주셔서 감사합니다. 최종 코드가 필요한 경우 여기 github 저장소가 있습니다.
github repo link
저와 연결해주세요
Udemy
Reference
이 문제에 관하여(Yup 및 React Hook 양식으로 간편하게 양식 유효성 검사), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/laribright/form-validation-a-breeze-with-yup-and-react-hook-form-3pde텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)