Archive

[React] Formik / Yup

manon_e 2021. 11. 22. 14:45
반응형

https://formik.org/

 

Formik

React hooks and components for hassle-free form validation. The world's leading companies use Formik to build forms and surveys in React and React Native.

formik.org

 

 

Formik ?

Formik is the world's most popular open source form library for React and React Native.

 

 

 

 

 > 회원가입같이 데이터를 입력해서 서버에 보내는 페이지를 react로 구현하다보면 state, eventhandler, validate 등의

    여러 코드들이 많이 발생한다. 이런 form 형태의 입력을 쉽게 처리해주는 라이브러리가 Formik이다.

    (사용자에게 입력을 받고(input) 값을 검증하는 코드(이메일, 패스워드 일치 등), 사용자가 입력했는지 확인 등)

 >  간단한 객체 스키마 검증 라이브러리 yup과 같이 많이 사용된다.

 

 

 

 

✔️ 공식문서 내용

 

Formik is a small library that helps you with the 3 most annoying parts:

  1. Getting values in and out of form state
  2. Validation and error messages
  3. Handling form submission

 

 

 

Why not Redux-Form?

1. Form state is inherently ephemeral and local, so tracking it in Redux (or any kind of Flux library) is unnecessary

2. Redux-Form calls your entire top-level Redux reducer multiple times ON EVERY SINGLE KEYSTROKE. This is fine for small apps, but as your Redux app grows, input latency will continue to increase if you use Redux- Form.

3. Redux-Form is 22.5 kB minified gzipped (Formik is 12.7 kB)

 

 

Formik's goal was to create a scalable, performant, form helper with a minimal API that does the really really annoying stuff, and leaves the rest up to you.

 

 

 

 

Complementary Packages : Yup

 Yup for object schema validation. It has an API that's pretty similar to Joi / React PropTypes but is small enough for the browser and fast enough for runtime usage. 

 

 

 

 

 

 


 

 

Installation

npm install formik --save

 

 

 

The Gist

Formik keeps track of your form's state and then exposes it plus a few reusable methods and event handlers (handleChange, handleBlur, and handleSubmit) to your form via props. 

handleChange and handleBlur work exactly as expected--they use a name or id attribute to figure out which field to update.

import React from 'react';
import { Formik } from 'formik';

const Basic = () => (
  <div>
    <h1>Anywhere in your app!</h1>
    <Formik
      initialValues={{ email: '', password: '' }}
      validate={values => {
        const errors = {};
        if (!values.email) {
          errors.email = 'Required';
        } else if (
          !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
        ) {
          errors.email = 'Invalid email address';
        }
        return errors;
      }}
      onSubmit={(values, { setSubmitting }) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          setSubmitting(false);
        }, 400);
      }}
    >
      {({
        values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit,
        isSubmitting,
        /* and other goodies */
      }) => (
        <form onSubmit={handleSubmit}>
          <input
            type="email"
            name="email"
            onChange={handleChange}
            onBlur={handleBlur}
            value={values.email}
          />
          {errors.email && touched.email && errors.email}
          <input
            type="password"
            name="password"
            onChange={handleChange}
            onBlur={handleBlur}
            value={values.password}
          />
          {errors.password && touched.password && errors.password}
          <button type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </form>
      )}
    </Formik>
  </div>
);

export default Basic;

https://formik.org/docs/overview#the-gist

 

Overview | Formik

Formik documentation, tutorial, guides, and examples

formik.org

 

 

 

✔️ 참고영상

https://www.youtube.com/watch?v=u-CCnDayNJw 

 

 

 

 


 

 

Formik 사용예제

 

 

1. import <Formik>

    콘솔창에 찍어서 property 확인해보기.

import * as React from "react";
import { Formik } from "formik";

function RegisterPage() {
  return (
    <Formik>
      {(formik) => {
        console.log(formik);
      }}
    </Formik>
  );
}

export default RegisterPage;

 

 

 

2. initialValues에 기본값 설정 " " 

 

    <Formik
      initialValues={{         //기본값 설정
        name: "",
        email: "",
        password: "",
        confirmPassword: "",
      }}
    >
      {(formik) => {
        <div>
          <h1>sign up</h1>
          {console.log(formik)}    
        </div>;
      }}
    </Formik>

 

 

3. <input>할 textfield.js 생성한다. props로 넘겨받은 값 사용할 react hook useField사용한다.

 

 

 

useField is a custom React hook that will automagically help you hook up inputs to Formik. You can and should use it to build your own custom input primitives. There are 2 ways to use it.

//signup.js
return (
  <Formik
  ....
 {(formik) => (
        <div>
          <h1 className="my-4 font-weignt-bold-display-4">sign up</h1>
          <Form>
            <TextField label="name" name="name" type="text" />
          </Form>
        </div>
      )}
//textField.js
import React from "react";
import { useField } from "formik";

function TextField(props) {
  const [Field, meta] = useField(props);
  console.log(Field, meta);
  return (
    <div>
      <input type="text" />
    </div>
  );
}

export default TextField;

console.log(Field, meta)

 

//signupPage에 input할 항목 채워넣고 버튼도 만들어준다.
<Form>
            <TextField label="name" name="name" type="text" />
            <TextField label="email" name="email" type="email" />
            <TextField label="password" name="password" type="password" />
            <TextField
              label="confirmPassword"
              name="confirmPassword"
              type="password"
            />
            <button className="btn btn-dark mt-3" type="submit">
              Create Account
            </button>
          </Form>
//textField.js
import React from "react";
import { useField } from "formik";

function TextField({ label, ...props }) {
  const [Field, meta] = useField(props);
  return (
    <div className="mb-2">
      <label htmlFor={Field.name}>{label}</label>
      <input
        className="form-control shadow-none"
        {...Field}
        {...props}
        autoComplete="off"
      />
    </div>
  );
}

export default TextField;

 

 

 

 

4. Yup 사용하여 유효성 검사 로직 추가한다.

  const validate = Yup.object({
    username: Yup.string()
      .max(15, "Must be 15 characters or less")
      .min(5, "Must be 5 characters or more")
      .required("Required"),
    email: Yup.string().email("Email is invalid").required("Required"),
    password: Yup.string()
      .min(6, "Password must be at least 6 charaters")
      .required("Password is required"),
    confirmPassword: Yup.string()
      .oneOf([Yup.ref("password"), null], "Password must match")
      .required("Confirm password is required"),
    acceptedTerms: Yup.boolean()
      .required("Required")
      .oneOf([true], "You must accept the terms and policy"),
  });

 

 

 

 

 

5. 이미존재하는 유저라면 reset / 유효성 검사 통과하면 success alert 추가하고 login 페이지로 이동한다.

  const handleOnSubmit = async (values, actions) => {
    await axios
      .post(`${baseurl}/users`, values)
      .then((res) => {
        actions.setSubmitting(false);
        alert("Thanks for signing up");
        history.push("./login");
      })
      .catch((error) => {
        console.log(error);
        actions.resetForm();
        alert("User already exist");
      });
  };

 

 

 

 

 

[전체 코드] https://github.com/manonkim/internship

 

GitHub - manonkim/internship: Signup page(formik/yup)

Signup page(formik/yup). Contribute to manonkim/internship development by creating an account on GitHub.

github.com

 

반응형

'Archive' 카테고리의 다른 글

[TS] TypeScript Setting / tsconfig.json  (0) 2021.11.25
[21.11.25] 두 자연수의 누적값 중 최솟값  (0) 2021.11.25
Authentication / Authorization ( 인증/인가 )  (0) 2021.11.19
[TIL] Strapi  (0) 2021.11.18
[JS] this  (0) 2021.11.13