Next에서 Form 라이브러리를 선택하려면 Form과 React Hook Form을 설치해 보십시오

개요


나는 개인적으로 아래의 관점에서 출발하여React Hook Form이 추천하는 방향으로 전진할 것이라고 생각한다

  • React Hook Form 문서에 일본어도 지원한다고 나와 있음
  • useFormContext,FormProvider 등 기존 React Context와 같은 사용감으로 코드를 알기 쉽게
  • ref={register} 정말 즐거웠어요
  • 비교


    input을 입력할 때 렌더링 횟수 등 성능이 측정되지 않았습니다
    실장만 달라요.
    그냥 해줬어React Hook Form 문서의 알기 쉬운 비교 표.참고할 수 있을 것 같아(아니, 사실 조사 안 하면 안 될 것 같아...알아...)

    컨디션


    package.json
    {
      "dependencies": {
        "@hookform/resolvers": "1.3.2",
        "formik": "2.2.6",
        "next": "10.0.3",
        "react": "17.0.1",
        "react-dom": "17.0.1",
        "react-hook-form": "6.14.0",
        "yup": "0.32.8"
      }
    }
    

    모든 코드

  • Formik
  • React Hook Form
  • Formik


    설치하다.

  • yarn add formik yup
  • yarn add -D @types/yup
  • 기본적


    사용useFormik된 훅의 쓰기와 사용<Formik /><Field />된 구성 요소의 쓰기는 두 가지가 있다.
    훅을 사용하는 작법은 자습서 코드을 참고하십시오.
    이번에는 익숙한 구성 요소의 작법을 써야 한다
    한form을presenter,container,정의 구성 요소의 세 부분으로 나눈다
    각자가 대체로 다음과 같은 작용을 한다
  • presenter→form의 ui
  • container→useEffect 또는 부작용
  • <Formik />
  • presenter


    교정에서 발췌하다.
    Form과 Field는 Formik부터 유행했어요.
    export type ExampleFormValues = {
      firstName: string;
      lastName: string;
      email: string;
    };
    
    export const ExampleFormPresenter = (): JSX.Element => (
      <Form>
        <label htmlFor="firstName">First Name</label>
        <Field name="firstName" type="text" />
        <ErrorMessage name="firstName" />
        <label htmlFor="lastName">Last Name</label>
        <Field name="lastName" type="text" />
        <ErrorMessage name="lastName" />
        <label htmlFor="email">Email Address</label>
        <Field name="email" type="email" />
        <ErrorMessage name="email" />
        <button type="submit">Submit</button>
      </Form>
    );
    

    container


    예) 부모 구성 요소 옆에서 props를 통해form의 값을 바꾸고 싶을 때
    export type ExampleFormContainerProps = {
      formValues?: ExampleFormValues;
    };
    
    export const ExampleFormContainer = ({
      formValues,
    }: ExampleFormContainerProps): JSX.Element => {
      const { setValues } = useFormikContext<ExampleFormValues>();
    
      useEffect(() => {
        setValues(formValues);
      }, [formValues]);
    
      return <ExampleFormPresenter />;
    };
    

    <Formik />

    <Formik />로 컨테이너를 싸다
    export type ExampleFormProps = {
      handleSubmit: (values: ExampleFormValues) => void;
      formValues?: ExampleFormValues;
    };
    
    export const ExampleForm = ({
      handleSubmit,
      formValues,
    }: ExampleFormProps): JSX.Element => {
      const onSubmit = (values: ExampleFormValues) => {
        handleSubmit(values);
      };
    
      const initialValues: ExampleFormValues = formValues || {
        firstName: '';
        lastName: '';
        email: '';
      };
    
      return (
        <Formik
          initialValues={initialValues}
          onSubmit={onSubmit}
        >
          <ExampleFormContainer formValues={formValues} />
        </Formik>
      );
    };
    

    발리


    발리 규칙을 혼자 정의할 수 있어요.
    단, 어느 정도 통용되는 규칙을 사용하고자 하기 때문에 Yup이 사용할 수 있는 설치예validationSchema를 기재합니다
    yup 모니터 일람
    Formink의validationSchoema(prop)에yup이 정의한 검증 규칙을 넣는 느낌
    import * as Yup from "yup";
    
    export const validationSchema = Yup.object().shape({
      firstName: Yup.string().required(),
      lastName: Yup.string().required(),
      email: Yup.string().email(),
    });
    
    export const ExampleForm = ({
      // ....省略
    }: ExampleFormProps): JSX.Element => {
      // ....省略
      return (
        <Formik
          validationSchema={validationSchema}
        >
        // ....省略
      );
    };
    

    오류 메시지의 일본어화


    이러다가는 발리에서 자동사냥을 할 때 잘못된 정보가 일본어화된다
    setLocal의 객체 속성 참조여기.
    import { setLocale } from "yup";
    setLocale({
      mixed: {
        required: () => `入力必須項目です。`,
      },
      string: {
        min: ({ min }) => `${min}文字以上で入力して下さい。`,
      },
    });
    

    사용자 정의 버전을 Yup으로 정의

    <Formik />value는 이전 형식의 영향을 받습니다 (string ()는string입니다)
    예) 문자열이 test('testの名前', 'エラーメッセージ', (value): boolean => {カスタムバリデーションの定義})인지 여부
    const validationSchema = Yup.object().shape({
      date: Yup.string()
        .required()
        .test("checkDateFormat", "日付の形式が間違ってます", (value): boolean => {
          if (!dayjs(value).isValid()) return false;
          const format = "YYYY/MM/DD";
          return dayjs(value, format).format(format) === value;
        }),
    });
    

    FieldArray


    같은 name의 input에 배열할 때 사용하는 것
    formik 문서의 해당 위치
    설치 예
    type Friend = {
      name: string;
      email: string;
    };
    
    export type ExampleFormValues = {
      friends: Friend[];
    };
    
    // ...省略
    <Field name="friends">
      {({ field }: FieldProps<ExampleFormValues["friends"]>) => (
        <FieldArray name={field.name}>
          {({ remove, push }: ArrayHelpers) => (
            <div>
              {field.value.map((f, i) => (
                <div key={i}>
                  <div>
                    <InputText
                      name={`friends.${i}.name`}
                      value={f.name}
                      onChange={field.onChange}
                    />
                    <ErrorMessage name={`friends.${i}.name`} />
                  </div>
                  <div>
                    <InputText
                      name={`friends.${i}.email`}
                      value={f.email}
                      onChange={field.onChange}
                    />
                    <ErrorMessage name={`friends.${i}.email`} />
                  </div>
                  <button
                    type="button"
                    onClick={() => {
                      remove(i);
                    }}
                  >
                    削除
                  </button>
                </div>
              ))}
              <button
                type="button"
                onClick={() => {
                  push({ name: "", email: "" });
                }}
              >
                友達追加
              </button>
            </div>
          )}
        </FieldArray>
      )}
    </Field>;
    
    ArreyHelpers가 리스트를 처리하기 위해 편리한 helper를 준비했습니다.

    React Hook Form


    설치하다.

    YYYY/MM/DD

    기본적


    비교하기 편리하도록formik의 실현과 같은 느낌(presenter,container,)으로 실현

    presenter


    presenter,container,로 나눌 때 하위 구성 요소는useFormContext로 context를 구동하는 느낌으로 여겨집니다
    export type ExampleFormValues = {
      firstName: string;
      lastName: string;
      email: string;
    };
    
    export type ExampleFormPresenterProps = {
      onSubmit: (values: ExampleFormValues) => void;
    };
    
    export const ExampleFormPresenter = ({
      onSubmit,
    }: ExampleFormPresenterProps): JSX.Element => {
      const {
        register,
        handleSubmit,
        errors,
      } = useFormContext<ExampleFormValues>();
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <div>
            <label htmlFor="firstName">firstName</label>
            <input name="firstName" ref={register} />
            {errors.firstName && <p>{errors.firstName.message}</p>}
          </div>
          <div>
            <label htmlFor="lastName">lastName</label>
            <input name="lastName" ref={register} />
            {errors.lastName && <p>{errors.lastName.message}</p>}
          </div>
          <div>
            <label htmlFor="email">email</label>
            <input name="email" ref={register} />
            {errors.email && <p>{errors.email.message}</p>}
          </div>
          <button type="submit">Submit</button>
        </form>
      );
    };
    

    container


    예) 부모 구성 요소 옆에서 props를 통해form의 값을 바꾸고 싶을 때
    export type ExampleFormContainerProps = {
      onSubmit: (values: ExampleFormValues) => void;
      formValues?: ExampleFormValues;
    };
    
    export const ExampleFormContainer = ({
      onSubmit,
      formValues,
    }: ExampleFormContainerProps): JSX.Element => {
      const { reset } = useFormContext<ExampleFormValues>();
    
      useEffect(() => {
        reset(formValues);
      }, [formValues]);
    
      return <ExampleFormPresenter onSubmit={onSubmit} />;
    };
    

    <FormProvider />


    hook은 주요한 사용 방법이기 때문에form이 1개의 구성 요소로 완성된 경우 사용하지 않지만 하위 구성 요소로 파생된 경우yarn add react-hook-form @hookform/resolvers 사용
    methods가
    export type ExampleFormProps = {
      onSubmit: (values: ExampleFormValues) => void;
      formValues?: ExampleFormValues;
    };
    
    export const ExampleForm = ({
      onSubmit,
      formValues,
    }: ExampleFormProps): JSX.Element => {
      const methods = useForm<ExampleFormValues>();
    
      return (
        <FormProvider {...methods}>
          <ExampleFormContainer onSubmit={onSubmit} formValues={formValues} />
        </FormProvider>
      );
    };
    
    <FormProvider />에 전달된 서브 구성 요소들<FormProvider>이기 때문에useForm에서 사용할 수 있는 방법

    발리


    빌딩의 발리는 여러 날 있지만 이번엔 Yup 사용을 전제로 하기 때문에 사랑을 끊는다
    문서 이해하기 쉬우니까 보면 인상이 잘 잡힐 것 같아요.
    Yup을 사용할 때useForm의 매개 변수를 Resolver로 건네주면useFormContext
    import { yupResolver } from "@hookform/resolvers/yup";
    
    // 前に記載したExampleFormと値が変わってることには触れないで
    export const validationSchema = Yup.object().shape({
      name: Yup.string().required(),
      age: Yup.number().required(),
      fruit: Yup.mixed().oneOf(["apple", "banana", "lemon"]).required(),
      category: Yup.mixed().oneOf(["dog", "cat", "rabbit"]).required(),
    });
    
    export const ExampleForm = ({
      onSubmit,
      formValues,
    }: ExampleFormProps): JSX.Element => {
      const methods = useForm<ExampleFormValues>({
        resolver: yupResolver(validationSchema),
      });
    
      return (
        <FormProvider {...methods}>
          <ExampleFormContainer onSubmit={onSubmit} formValues={formValues} />
        </FormProvider>
      );
    };
    

    useFieldArray


    ForminkyupResolver의 hook 버전
    이것도 자세히문서 설치 방법을 기재하였는데, 문서를 읽으면 실제 이미지를 잡을 수 있을 것이다
    type Friend = {
      name: string;
      email: string;
    };
    
    export type HookFormValues = {
      friends: Friend[];
    };
    
    export const HookFormPresenter = ({
      onSubmit,
    }: HookFormPresenterProps): JSX.Element => {
      const {
        register,
        handleSubmit,
        errors,
        control,
      } = useFormContext<HookFormValues>();
      const { fields, append, remove } = useFieldArray<Friend>({
        control,
        name: "friends",
      });
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <div>
            {fields.map((f, i) => (
              <div key={f.id}>
                <input name={`friends[${i}].name`} ref={register} />
                <input name={`friends[${i}].email`} ref={register} />
              </div>
            ))}
          </div>
          <button
            onClick={() => {
              append({ name: "", email: "" });
            }}
          >
            友達追加
          </button>
          <button
            onClick={() => {
              remove();
            }}
          >
            全削除
          </button>
          <button type="submit">Submit</button>
        </form>
      );
    };
    
    <FieldArray>append 외에 배열 처리에 편리한 방법도 준비했다

    좋은 웹페이지 즐겨찾기