리액트에서 form control을 보다 편하게 할 수 있게 해주기 위해서 만들어진 라이브러리.
보통 form을 리액트에서 사용하다 보면, 성능(re-render등)이슈도 신경써야하고, 일일이 state로 관리해야한다는 점도 은근 성가신데, 이런 귀찮은 일들을 깔끔하게 대신 처리해준다는 점에서 인기가 있다.
회원가입 처리 등 여러가지 form을 예외처리와 함께 다뤄야 하는 경우에 매우 쉽고 깔끔하게 사용할 수 있다는 장점이 있다.
아래 예제만 보아도 거의 모든 기능을 사용할 수 있다
1. Formik 생성하기
Formik은 컴포넌트 모양으로 생성해낼 수도, useFormik을 사용해서 변수에 담아 사용할 수도 있다.
생성한 이후, initialValues
, validate
, onSubmit
, 등의 prop을 사용할 수 있다.
initialValues
: form에서 관리할 값들을 모아놓는 객체
validate
: validation 확인 로직을 담아둔다
onSubmit
: submit 이벤트 발생 시 실행할 로직 기재
change event와 blur 이벤트의 경우 handleChange, handleBlur를 사용해 formik에서 알아서 찰떡같이 처리해준다
import { Formik } from "formik";
const 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.eemail = 'Invalid email address';
}
return errors;
}
// 컴포넌트 처럼 선언
<Formik
initialValues={{ email: '', password: '' }}
validate={validate}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
<TextField
error={Boolean(formik.errors.email)}
helperText={formik.errors.email}
label="Email"
margin="normal"
name="email"
onBlur={formik.handleBlur}
onChange={formik.handleChange}
type="email"
value={formik.values.email}
variant="outlined"
/>
<Button
color="primary"
disabled={formik.isSubmitting}
fullWidth
size="large"
type="submit"
variant="contained"
>
Sign In Now
</Button>
</Formik>
import { useFormik } from "formik";
const 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.eemail = 'Invalid email address';
}
return errors;
}
// useFormik을 활용해 변수에 담아서 사용
const formik = useFormik({
initialValues: {
email: '',
password: ''
},
validate,
onSubmit: ((values, {setSubmiiting}) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}
});
....
return (
<TextField
error={Boolean(formik.errors.email)}
helperText={formik.errors.email}
label="Email"
margin="normal"
name="email"
onBlur={formik.handleBlur}
onChange={formik.handleChange}
type="email"
value={formik.values.email}
variant="outlined"
/>
<Button
color="primary"
disabled={formik.isSubmitting}
fullWidth
size="large"
type="submit"
variant="contained"
>
Sign In Now
</Button>
)
자주 사용되는 것이 handleChange
와 handleBlur
이다.
이 두개는 이름에서 느낌이 오듯이, change event, blur event가 발생할 때 알아서 찰떡같이 value를 업데이트해주기 때문에 매우 편하다.
앞서서 보았듯, validation
에 기재되는 로직은, 우리가 흔히 작성하는 일반 자바스크립트 유효성 로직과 큰 차이가 없다.
물론 이렇게 적어도 좋지만, 처리해야되는 value가 많아질 수록 코드가 매우 길어지며..
뭣보다 누가봐도 뻔한 로직을, 직접 일일이 치고 관리를 해야한다는 점에서 매우 귀찮다.
예로, email을 validate 할 경우, 누구나 당연히 @골뱅이가 들어가고 .이 들어가야한다는 조건을 넣어야되는데, 이걸 프로젝트 할때마다 긁어다가 사용하는건 어떤 면에선 귀찮다.
이런 뻔한 validation 처리를 위해서 생겨난 것이 Yup이며, formik에서 validation 처리 시 yup을 사용하길 권장하고 있어, yup을 사용한 예시도 함께 보자.
const formik = useFormik({
initialValues: {
email: 'demo@devias.io',
password: 'Password123'
},
validationSchema: Yup.object({
email: Yup
.string()
.email(
'Must be a valid email')
.max(255)
.required(
'Email is required'),
password: Yup
.string()
.max(255)
.required(
'Password is required')
}),
onSubmit: () => {
router.push('/');
}
});
yup을 사용하는 경우에는 validationSchema
라는 key를 선언해준 후, yup object를 만들어 각 value 별로 조건을 기재해두면 된다.
예로, string()
의 경우, string형태로 들어와야한다는 것이고,
string("must be string")
이런식으로 작성하면, string 조건에 만족하지 못할 시, 어떤 식으로 error를 반환 힐지 기재한다.
yup의 자세한 validation method는 yup 공식문서에 잘 나와있어, 예제를 보고 잘 따르기만 하면 금방 익힐 수 있다😃