React, Joi 및 Tailwind CSS로 양식 디자인

48335 단어 tailwindcssreactjoi

소개



프런트엔드 앱의 양식 처리 프로세스에서 중요한 사항 중 하나는 데이터를 백엔드로 보내기 전에 모든 데이터가 사실인지 확인해야 하지만 양식 유효성 검사 프로세스는 약간 어렵고 필요한 세부 정보가 많이 포함되어 있다는 것입니다. 양식 데이터의 유효성을 검사해야 하는 모든 프로젝트에서 이를 반복합니다.
따라서 이 문제를 해결하기 위해 이 문제를 처리하거나 해결하는 데 사용되는 수십 개의 패키지가 있으며 이러한 패키지 중 하나가 Joi입니다.
Joi는 프런트 엔드 프로젝트에서 사용하는 양식 데이터의 유효성을 검사하는 데 사용하는 패키지입니다.
그리고 이 글에서는 reacttailwindJoi 으로 간단한 로그인 폼을 디자인할 예정이니 시작해보자...👉

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));
    }
  }
}


  • 먼저 LoginForm 구성 요소에서 formValidate 함수를 가져옵니다.
    이 함수는 두 개의 인수를 사용합니다.
  • 폼데이터
  • 스키마


  • 발견되면 입력 오류를 포함하는 오류 객체를 반환합니다.
  • 그런 다음 Joi를 구성 요소로 가져오고 작업이 양식 데이터와 비교할 Joi 스키마를 정의합니다.
  • 양식 데이터 오류 개체를 포함할 상태를 만들 것입니다
  • .
  • 그런 다음 처리기를 제출할 때 오류가 있는지 확인하고 그에 따라 오류를 상태로 업데이트합니다
  • .
  • 마지막으로 오류가 있는 경우 각 입력 아래에 위험 경고를 표시합니다.

  • 그리고 이것은 최종 코드입니다.

    로그인폼.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와 같이 사용할 수 있는 다른 패키지가 많이 있지만 원칙은 동일합니다.
    이 글이 도움이 되길 바라며, 읽어주셔서 감사합니다. 다음 글에서 뵙겠습니다.

    좋은 웹페이지 즐겨찾기