React, Joi 및 Tailwind CSS로 양식 디자인
48335 단어 tailwindcssreactjoi
소개
프런트엔드 앱의 양식 처리 프로세스에서 중요한 사항 중 하나는 데이터를 백엔드로 보내기 전에 모든 데이터가 사실인지 확인해야 하지만 양식 유효성 검사 프로세스는 약간 어렵고 필요한 세부 정보가 많이 포함되어 있다는 것입니다. 양식 데이터의 유효성을 검사해야 하는 모든 프로젝트에서 이를 반복합니다.
따라서 이 문제를 해결하기 위해 이 문제를 처리하거나 해결하는 데 사용되는 수십 개의 패키지가 있으며 이러한 패키지 중 하나가 Joi입니다.
Joi는 프런트 엔드 프로젝트에서 사용하는 양식 데이터의 유효성을 검사하는 데 사용하는 패키지입니다.
그리고 이 글에서는 react 과 tailwind 과 Joi 으로 간단한 로그인 폼을 디자인할 예정이니 시작해보자...👉
1. 프로젝트 초기화 및 종속성 설치
먼저 터미널에 다음 명령을 입력하여 컴퓨터에서 다음Repo을 복제합니다.
git clone https://github.com/ahmedmohmd/login-form
이제 프로젝트의 구조는 다음과 같습니다.
|
├── public
│ └── index.html
├── README.md
├── src
│ ├── App.js
│ ├── components
│ │ └── LoginForm.jsx
│ ├── index.css
│ ├── index.js
│ └── utils
│ └── formValidate.js
└── tailwind.config.js
├── package.json
├── package-lock.json
├── postcss.config.js
└── .gitignore
이제 터미널에 다음 명령을 입력하여 프로젝트 종속성을 설치합니다.
npm i
2. JSX 및 양식 스타일 만들기
이제 멋진 양식을 만들 준비가 되었다고 말할 수 있습니다. 먼저 양식
JSX
과 스타일을 만듭니다.LoginForm.jsx
로 이동하여 다음 코드를 입력합니다.로그인폼.jsx:
function LoginForm() {
return (
<div className="flex items-center justify-center min-h-screen bg-wi-500 min-w-screen">
<div className="container flex items-center justify-center p-3 mx-auto">
<form className="flex flex-col items-center justify-center w-full gap-10 px-5 py-5 shadow-xl rounded-2xl sm:w-1/3">
<div class="w-full flex flex-col justify-center items-stretch gap-2">
<label for="email" class="block font-medium text-gray-900 ">
<span class="bg-purple-100 text-purple-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Email
</span>
</label>
<input
type="email"
class="placeholder:text-slate-400 placeholder:font-bold outline-none bg-gray-50 border border-gray-300 text-slate-500 font-bold text-md rounded-xl block w-full p-2.5"
placeholder="[email protected]"
/>
</div>
<div class="w-full flex flex-col justify-center items-stretch gap-2">
<label for="email" class="block font-medium text-gray-900 ">
<span class="bg-purple-100 text-purple-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Password
</span>
</label>
<input
type="password"
class="placeholder:text-slate-400 placeholder:font-bold outline-none bg-gray-50 border border-gray-300 text-slate-500 font-bold text-md rounded-xl block w-full p-2.5"
placeholder="•••••••••"
/>
</div>
<button
type="submit"
class="text-white bg-blue-500 hover:bg-blue/80 justify-center gap-2 focus:ring-4 focus:outline-none focus:ring-blue-500/50 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:hover:bg-[#FF9119]/80 dark:focus:ring-[#FF9119]/40 mr-2 mb-2"
>
<span>Send</span>
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-6 h-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M13 5l7 7-7 7M5 5l7 7-7 7"
/>
</svg>
</button>
</form>
</div>
</div>
);
}
3. 입력 및 양식 제출 처리
구성 요소의 빌드
JSX
및 스타일 후에 입력 값과 이벤트를 처리합니다.로그인폼.jsx:
function LoginForm() {
const [formData, setFormData] = useState({
email: "",
password: "",
});
return (
<div className="flex items-center justify-center min-h-screen bg-wi-500 min-w-screen">
<form onSubmit={handleSubmit}>
//* Email Input
<input
onChange={(event) => {
setFormData({ ...formData, email: event.target.value });
}}
/>
//* Password Input
<input
onChange={(event) => {
setFormData({ ...formData, password: event.target.value });
}}
/>
</form>
</div>
);
function handleSubmit(event) {
event.preventDefault();
console.log(JSON.stringify(formData));
}
}
위의 코드에서 모든 입력에
onClick
이벤트를 입력하고 입력과 같은 입력 값의 변경 사항을 수신한 다음 formData
상태의 키(이메일, 암호)에 할당합니다.입력 값의 변경 사항을 처리한 후 제출 프로세스를 처리하기 위해 양식에서
onSubmit
이벤트를 만듭니다.먼저
event.preventDefault()
를 입력하여 양식을 제출하는 기본 동작을 방지한 다음 콘솔에 JSON 데이터로 formData
를 기록합니다.4. Joi의 양식 데이터 유효성 검사
formValidate.js:
//* Form Validate Function
const formValidate = (formData, schema) => {
const errors = {};
const options = { abortEarly: false };
const { error } = schema.validate(formData, options);
if (!error) return null;
if (error)
for (let item of error.details) {
errors[item.path[0]] = item.message;
}
return errors;
};
export { formValidate };
로그인폼.jsx:
const loginFormSchema = Joi.object({
email: Joi.string()
.email({
tlds: { allow: ["com"] },
})
.required(),
password: Joi.string().min(4).max(8).required(),
});
function LoginForm() {
const [errors, setErrors] = useState({
email: "",
password: "",
});
return (
<div>
<form>
//* Email Input
<input type="password" placeholder="•••••••••" />
{errors.email ? (
<div
class="flex p-4 text-sm text-white bg-red-400 rounded-lg dark:bg-red-200"
role="alert"
>
<svg
class="inline flex-shrink-0 mr-3 w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"
></path>
</svg>
<div>{errors.email}</div>
</div>
) : null}
//* Password Input
<input type="email" placeholder="[email protected]" />
{errors.password ? (
<div
class="flex p-4 text-sm text-white bg-red-400 rounded-lg dark:bg-red-200"
role="alert"
>
<svg
class="inline flex-shrink-0 mr-3 w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"
></path>
</svg>
<div>{errors.password}</div>
</div>
) : null}
</form>
</div>
);
function handleSubmit(event) {
event.preventDefault();
const errorsResult = formValidate(formData, loginFormSchema);
if (errorsResult) {
setErrors(errorsResult);
} else {
setErrors({});
console.log(JSON.stringify(formData));
}
}
}
formValidate
함수를 가져옵니다.이 함수는 두 개의 인수를 사용합니다.
발견되면 입력 오류를 포함하는 오류 객체를 반환합니다.
그리고 이것은 최종 코드입니다.
로그인폼.jsx:
import { useState } from "react";
import Joi, { required } from "joi";
import { formValidate } from "../utils/formValidate";
const loginFormSchema = Joi.object({
email: Joi.string()
.email({
tlds: { allow: ["com"] },
})
.required(),
password: Joi.string().min(4).max(8).required(),
});
function LoginForm() {
const [formData, setFormData] = useState({
email: "",
password: "",
});
const [errors, setErrors] = useState({
email: "",
password: "",
});
return (
<div className="flex items-center justify-center min-h-screen bg-wi-500 min-w-screen">
<div className="container flex items-center justify-center p-3 mx-auto">
<form
onSubmit={handleSubmit}
className="flex flex-col items-center justify-center w-full gap-10 px-5 py-5 shadow-xl rounded-2xl sm:w-1/3"
>
<div class="w-full flex flex-col justify-center items-stretch gap-2">
<label for="email" class="block font-medium text-gray-900 ">
<span class="bg-purple-100 text-purple-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Email
</span>
</label>
<input
type="email"
class="placeholder:text-slate-400 placeholder:font-bold outline-none bg-gray-50 border border-gray-300 text-slate-500 font-bold text-md rounded-xl block w-full p-2.5"
placeholder="[email protected]"
onChange={(event) => {
setFormData({ ...formData, email: event.target.value });
}}
/>
{errors.email ? (
<div
class="flex p-4 text-sm text-white bg-red-400 rounded-lg dark:bg-red-200"
role="alert"
>
<svg
class="inline flex-shrink-0 mr-3 w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"
></path>
</svg>
<div>{errors.email}</div>
</div>
) : null}
</div>
<div class="w-full flex flex-col justify-center items-stretch gap-2">
<label for="email" class="block font-medium text-gray-900 ">
<span class="bg-purple-100 text-purple-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded">
Password
</span>
</label>
<input
type="password"
class="placeholder:text-slate-400 placeholder:font-bold outline-none bg-gray-50 border border-gray-300 text-slate-500 font-bold text-md rounded-xl block w-full p-2.5"
placeholder="•••••••••"
onChange={(event) => {
setFormData({ ...formData, password: event.target.value });
}}
/>
{errors.password ? (
<div
class="flex p-4 text-sm text-white bg-red-400 rounded-lg dark:bg-red-200"
role="alert"
>
<svg
class="inline flex-shrink-0 mr-3 w-5 h-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"
></path>
</svg>
<div>{errors.password}</div>
</div>
) : null}
</div>
<button
type="submit"
class="text-white bg-blue-500 hover:bg-blue/80 justify-center gap-2 focus:ring-4 focus:outline-none focus:ring-blue-500/50 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:hover:bg-[#FF9119]/80 dark:focus:ring-[#FF9119]/40 mr-2 mb-2"
>
<span>Send</span>
<svg
xmlns="http://www.w3.org/2000/svg"
className="w-6 h-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M13 5l7 7-7 7M5 5l7 7-7 7"
/>
</svg>
</button>
</form>
</div>
</div>
);
function handleSubmit(event) {
event.preventDefault();
const errorsResult = formValidate(formData, loginFormSchema);
if (errorsResult) {
setErrors(errorsResult);
} else {
setErrors({});
console.log(JSON.stringify(formData));
}
}
}
export default LoginForm;
그리고 최종 결과는 다음과 같습니다.
결론
이 기사를 읽은 후 Joi 패키지를 살펴보고 유효성 검사 프로세스에서 더 쉽게 사용할 수 있는 방법을 살펴봐야 합니다. Joi와 같이 사용할 수 있는 다른 패키지가 많이 있지만 원칙은 동일합니다.
이 글이 도움이 되길 바라며, 읽어주셔서 감사합니다. 다음 글에서 뵙겠습니다.
Reference
이 문제에 관하여(React, Joi 및 Tailwind CSS로 양식 디자인), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ahmedmohmd/design-your-forms-with-react-joi-and-tailwind-css-7op텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)