여행가는개발자

Yup 본문

React

Yup

kimsoonil 2023. 9. 15. 13:28
728x90
반응형

Yup

Yup은 Form validation을 위한 라이브러리이다.

Yup schema object는 객체를 유효성 검증하는 데에 책임이 있는 이뮤터블 객체이다. 각 validator에 상응하는 고유의 메서드를 갖고 있으므로, 위에서 보듯이 여러개를 조합하여 원하는 data validation이 가능하다.

string, integer, date, boolean, array, object 와 같은 기본적인 타입과 더불어서 required(also notRequired), email, positive와 같은 것들도 제공한다.

const checkoutAddressSchema = yup.object().shape({
  email_address: yup
    .string()
    .email()
    .required(),
  full_name: yup.string().required(),
  house_no: yup
    .number()
    .required()
    .positive()
    .integer(),
  address_1: yup.string().required(),
  address_2: yup.string(),
  post_code: yup.string().required(),
  timestamp: yup.date().default(() => new Date()),
})

Validating Objects with My Schema

이제 폼에 맞는 스키마를 만들었고, 이것을 우리가 받은 데이터를 검증하는 데 사용할 수 있다. 아래와 같은 데이터를 제출받았다고 할 때 검증해보자.

// Expected schema from form
// If object does not match this schema,
// it is not valid.
{
  email_address: email <required>,
  full_name: string <required>,
  house_no: int,
  address_1: string <required>,
  address_2: string,
  post_code: string <required>,
  timestamp: date <required>
}

실코드에 적용

import React from "react";
import * as Yup from "yup";
import { Formik } from "formik";
import {
  Box,
  Button,
  Checkbox,
  FormControlLabel,
  TextField,
  Container,
} from "@material-ui/core";
function SignUp(props) {
 

  return (
    <div className={classes.root}>
        <Box className={classes.loginContents}>
          <Container maxWidth="xs">
            <Formik
              initialValues={{
                email: "",
                name: "",
                password: "",
                terms: false,
              }}
              validationSchema={Yup.object().shape({
                email: Yup.string()
                  .email("이메일 형태로 입력해주세요")
                  .max(255)
                  .required("이메일을 입력해주세요"),
                name: Yup.string()
                  .max(255)
                  .required("이름을 입력해주세요")
                  .min(2, "이름을 2자 이상 입력해주세요"),
                password: Yup.string()
                  .max(255)
                  .required("비밀번호를 입력해주세요")
                  .min(10, "비밀번호를 10자 이상 입력해주세요"),
                terms: Yup.boolean().oneOf([true], ""),
              })}
              onSubmit={(values) => {
                console.log(values);
                // dispatch(userActions.register(values));
              }}
            >
              {({
                errors,
                handleBlur,
                handleChange,
                handleSubmit,
                isSubmitting,
                touched,
                values,
                control,
              }) => (
                <form name="form" onSubmit={handleSubmit}>
                  <TextField
                    error={Boolean(touched.name && errors.name)}
                    helperText={touched.name && errors.name}
                    fullWidth
                    label="이름 (2자 이상) *"
                    margin="normal"
                    name="name"
                    onChange={handleChange}
                    onBlur={handleBlur}
                    value={values.name}
                    variant="outlined"
                    inputProps={{ maxLength: 20 }}
                  />
                  <TextField
                    error={Boolean(touched.email && errors.email)}
                    helperText={touched.email && errors.email}
                    fullWidth
                    label="이메일 (example@gmail.com)"
                    margin="normal"
                    name="email"
                    onChange={handleChange}
                    onBlur={handleBlur}
                    type="test"
                    value={values.email}
                    variant="outlined"
                    inputProps={{ maxLength: 40 }}
                  />
                  <TextField
                    error={Boolean(touched.password && errors.password)}
                    helperText={touched.password && errors.password}
                    fullWidth
                    label="비밀번호 (영문,숫자,특문 중 2개조합, 10자 이상)"
                    margin="normal"
                    name="password"
                    onChange={handleChange}
                    onBlur={handleBlur}
                    type="password"
                    value={values.password}
                    variant="outlined"
                    inputProps={{ maxLength: 20 }}
                  />

                  <FormControlLabel
                    control={
                      <Checkbox
                        name="terms"
                        color="primary"
                        required
                        onChange={handleChange}
                        checked={values.terms}
                      />
                    }
                    label={
                      <Box component="div" fontSize={12}>
                        계정을 생성함으로써 서비스약관과 연계정보(CI) 및
                        개인정보보호정책에 동의합니다
                      </Box>
                    }
                  />
                  <Box my={2}>
                    <Button
                      fullWidth
                      size="large"
                      type="submit"
                      disabled={isSubmitting}
                      variant="contained"
                      disabled={!values.terms}
                      className={
                        values.terms
                          ? classes.ActivateBtn
                          : classes.anotherLoginBtn
                      }
                    >
                      회원가입
                    </Button>
                  </Box>
                </form>
              )}
            </Formik>
          </Container>
        </Box>
      </Box>
    </div>
  );
}

export default SignUp;

initialValues 에서 기본값으로 초기화하고
validationSchema 에서 스키마형태고 값을 유효성체크합니다.

728x90
반응형

'React' 카테고리의 다른 글

Json-server  (0) 2023.09.15
Typescript vs Javascript  (0) 2023.09.15
[Material UI]  (0) 2023.09.14
ESLint + Prettier  (4) 2023.09.14
React social login - Microsoft  (0) 2023.09.13