패키지 추가

회원가입시 폼 유효성 체크를 하기위해서 formik이라는 라이브러리와 yup이라는 라이브러리를 사용한다.

yarn add formik yup

사용자에게 처리 결과를 알려주기 위해서 3rd party 라이브러리인 react -toastify를 사용한다.

yarn add react-toastify

화면 구현

화면을 아래처럼 구성한다.

pages/sign-up/SignUp.tsx

const SignUp = (props: any) => {
  const submit = async (values: any) => {
    console.log(values);
    const {email, password, username} = values;
    try {
      await axios.post('/api/auth/signup', {email, password, username});

      toast.success('회원등록하였습니다. 로그인하세요', {
        position: "top-center",
        autoClose: 3000,
        hideProgressBar: false,
        closeOnClick: true,
        pauseOnHover: true,
        draggable: true,
        progress: undefined,
      });
      props.history.push('/login');
    } catch(e) {
      toast.error('실패하였습니다. 다시 시도하세요', {
        position: "top-center",
        autoClose: 3000,
        hideProgressBar: false,
        closeOnClick: true,
        pauseOnHover: true,
        draggable: true,
        progress: undefined,
      });
    }
  }
  return (
    <Formik
      initialValues={{ email: '', password: '', password2: '', username: ''}}
      onSubmit={submit}
      validationSchema={Yup.object().shape({
        email: Yup.string()
          .email("이메일형식으로 입력하세요")
          .required("필수필드 입니다."),
        password: Yup.string()
          .required("Required")
          .min(6, "6자이상 입력하세요"),
        password2: Yup.string()
          .oneOf([Yup.ref("password"), null], "패스워드가 일치하지 않습니다.")
          .required("패스워드가 일치하지 않습니다."),
        username: Yup.string()
          .required("필수필드 입니다.")
      })}>
      {
        ({values,
            errors,
            touched,
            handleChange,
            handleBlur,
            handleSubmit,
            isSubmitting }) => (<Form onSubmit={handleSubmit}>
          <Form.Group controlId="email">
            <Form.Label>Email address</Form.Label>
            <Form.Control name="email" placeholder="Enter email"
                          value={values.email}
                          onChange={handleChange} onBlur={handleBlur}
                          isValid={touched.email && !errors.email}
                          isInvalid={touched.email && errors.email ? true : false} />
            { touched.email && !errors.email && <Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback> }
            { touched.email && errors.email && <Form.Control.Feedback type="invalid">{errors.email}</Form.Control.Feedback> }
          </Form.Group>
          <Form.Group controlId="formGroupPassword">
            <Form.Label>Password</Form.Label>
            <Form.Control type="password" name="password" placeholder="enter Password"
                          value={values.password}
                          onChange={handleChange} onBlur={handleBlur}
                          isValid={touched.password && !errors.password}
                          isInvalid={touched.password && errors.password ? true : false} />
            { touched.password && !errors.password && <Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback> }
            { touched.password && errors.password && <Form.Control.Feedback type="invalid">{errors.password}</Form.Control.Feedback> }
          </Form.Group>
          <Form.Group controlId="formGroupPassword2">
            <Form.Label>confirm Password</Form.Label>
            <Form.Control type="password" name="password2" placeholder="confirm Password"
                          value={values.password2}
                          onChange={handleChange} onBlur={handleBlur}
                          isValid={touched.password2 && !errors.password2}
                          isInvalid={touched.password2 && errors.password2 ? true : false} />
            { touched.password2 && !errors.password2 && <Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback> }
            { touched.password2 && errors.password2 && <Form.Control.Feedback type="invalid">{errors.password2}</Form.Control.Feedback> }
          </Form.Group>
          <Form.Group controlId="formGroupName">
            <Form.Label>Name</Form.Label>
            <Form.Control type="text" name="username" placeholder="enter username"
                          value={values.username}
                          onChange={handleChange} onBlur={handleBlur}
                          isValid={touched.username && !errors.username}
                          isInvalid={touched.username && errors.username ? true : false} />
            { touched.username && !errors.username && <Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback> }
            { touched.username && errors.username && <Form.Control.Feedback type="invalid">{errors.username}</Form.Control.Feedback> }
          </Form.Group>
          <Button variant="primary" type="submit" disabled={isSubmitting}>
            Submit
          </Button>
        </Form>)
      }
    </Formik>
  );
}

export default SignUp;

입력필드는 4가지이다. email, name, 그리고, password는 동일한 값인지를 확인하기 위해서 2개를 추가한다.

Formik에는 이 4개의 입력필드의 초기값을 initialValues에 설정한다.

폼을 controlled component로 만들어 주는 요소는 Form.Control에 name 속성이다.  이 name 값들은 initialValues의 키 값들과 일치해야 한다. 이 것만 기억하면 나머지 것들은 어려울게 없다.

그리고 validation은 Formik의 validationSchema에 설정한다.