멋진 React Hook Form과 Material-UI Libraries를 사용한 React의 궁극적인 형식 검증!
콘텐츠 테이블
Installing libraries locally
Installing Material UI .
Creating the Needing Files .
Setting up the App.js .
Starting the application .
Working on the design of SignInForm .
styles.js File .
SignInForm Component .
Working with React-Hook-Form to Validate the data .
Email Field .
Password Field .
Checkbox .
Option 1 - Register .
Option 2 - Controller and render .
로컬에 라이브러리 설치
We need to install the npm modules necessary to build this project which means it will be saved as a dependency in our package.json
file.
We are going to install material-ui and react-hook-form library locally.
React Hook Form 패키지 설치하기
To install the react-hook-form
module we have to type the following command on the terminal located in the project directory:
yarn add [email protected]
I've installed the version 6.5.3.
머티리얼 UI 설치
To install the material-ui
module to give some styling to our example form, we have to type the following command:
yarn add @material-ui/[email protected]
yarn add @material-ui/[email protected]
필요한 파일 만들기
This commands are for people working on a MAC or Linux Machine, If you are on a windows you can install an emulator to type the commands as you were in a Linux Machine. Click here to download Hypermkdir components
touch components/SignInForm.js
touch styles.js
App.js 설정
In the App.js copy the following code or import and add the SignInForm component:
import React from 'react';
import SignInForm from './components/SignInForm';
const App = () => (
<div>
<SignInForm />
</div>
);
export default App;
애플리케이션 시작
You can start the application as you see in the tutorial in the introduction of this article with the following command:
yarn run start
SignInForm 디자인 작업
style.js 파일
In this file, we are gonna change some classes, colours and styles of the final design of our Sign In Form based on the material-ui
library.
import TextField from '@material-ui/core/TextField';
import { makeStyles, withStyles } from '@material-ui/core/styles';
const mingColor = '#387780';
const dartmouthGreenColor = '#2D7638';
const emeraldGreenColor = '#62C370';
export const CssTextField = withStyles({
root: {
'& label.Mui-focused': {
color: mingColor,
},
'& .MuiInput-underline:after': {
borderBottomColor: dartmouthGreenColor,
},
'&$checked': {
color: '#3D70B2',
},
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: dartmouthGreenColor,
},
'&:hover fieldset': {
borderColor: emeraldGreenColor,
},
'&.Mui-focused fieldset': {
borderColor: mingColor,
},
},
},
})(TextField);
export const useStyles = makeStyles(theme => {
return {
paper: {
margin: theme.spacing(4, 0),
display: 'flex',
color: '#387780',
flexDirection: 'column',
alignItems: 'center',
border: `1px solid ${emeraldGreenColor}`,
borderRadius: '2rem',
padding: '1.5rem 2.5rem',
},
avatar: {
margin: theme.spacing(3),
backgroundColor: emeraldGreenColor,
fontSize: 50,
},
form: {
marginTop: theme.spacing(4),
width: '100%',
},
submit: {
margin: theme.spacing(3, 0, 2),
backgroundColor: emeraldGreenColor,
color: 'white',
padding: '50 50',
},
link: {
color: mingColor,
textDecoration: 'none !important',
},
checkBox: {
color: `${emeraldGreenColor} !important`,
},
error: {
color: 'red',
},
};
});
SignInForm 구성 요소
This is the component with the styles defined in the previous file applied and using the material-ui
library for final design.
import React from 'react';
import { AccountCircle as AccountCircleIcon } from '@material-ui/icons';
import {
Avatar,
Grid,
Container,
CssBaseline,
FormControlLabel,
Button,
Link,
Checkbox,
Typography,
} from '@material-ui/core';
import { CssTextField, useStyles } from '../styles';
const SignInForm = () => {
const classes = useStyles();
const onSubmit = e => {
e.preventDefault();
console.log(e.target);
};
return (
<Container component='main' maxWidth='xs'>
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<AccountCircleIcon style={{ fontSize: 45 }} />
</Avatar>
<Typography component='h1' variant='h4'>
Sign in
</Typography>
<form className={classes.form} noValidate onSubmit={e => onSubmit(e)}>
<CssTextField
name='email'
label='Email Address'
variant='outlined'
margin='normal'
autoComplete='email'
className={classes.margin}
fullWidth
required
autoFocus
/>
<CssTextField
name='password'
label='Password'
type='password'
variant='outlined'
margin='normal'
fullWidth
required
autoComplete='current-password'
/>
<Grid container>
<Grid item xs>
<Link href='#' variant='body2' className={classes.link}>
Forgot password?
</Link>
</Grid>
<Grid item>
<FormControlLabel
label='Remember me'
control={
<Checkbox
className={classes.checkBox}
name='remember'
defaultValue={false}
/>
}
/>
</Grid>
</Grid>
<Button
type='submit'
fullWidth
variant='contained'
className={classes.submit}
>
Sign In
</Button>
<Grid container>
<Grid item>
<Link href='#' variant='body2' className={classes.link}>
{'New to this platform? Create an Acount.'}
</Link>
</Grid>
</Grid>
</form>
</div>
</Container>
);
};
export default SignInForm;
React-Hook-Form을 사용하여 데이터 유효성 검사하기
Here we are going to explain some tweaks to be able to validate the data in the SignInForm
component.
First, we need to import useForm
hook and the Controller
component from the library:
import { useForm, Controller } from 'react-hook-form';
After, initializing the styles in the SignInForm
component we are going to add the register
and handleSubmit
functions, and errors
and control
objects:
const { register, handleSubmit, errors, control } = useForm();
However, If you want to configure the useForm
hook more, you can add an object with the details that you want to specify:
// ...
const { register, handleSubmit, control, errors } = useForm({
mode: 'onChange',
reValidateMode: 'onChange',
defaultValues: {
email: '',
password: '',
remember: false,
},
});
// ...
We are gonna update our onSubmit
function and integrate it with handleSubmit
hook from useFrom
inside the form tag:
// ...
const onSubmit = data => alert(JSON.stringify(data));
// ...
<form
className={classes.form}
noValidate
onSubmit={handleSubmit(onSubmit)}
>
// ...
이메일 필드
In order to add each input field to the form data, we just need to reference the register
function in each component. For example, in an input
, we add the property ref. However, we are using material-ui
, so, to do the reference to the register function we use the property inputRef
instead. See the example below:
// ...
<CssTextField
name='email'
label='Email Address'
variant='outlined'
margin='normal'
autoComplete='email'
className={classes.margin}
fullWidth
required
autoFocus
inputRef={register}
/>
// ...
We can add an object to the register function to be able to set up different functionalities. For instance, in the email, we want the email to be required
and personalize the message
that the user will see if the email field is blank. Additionally, we want the email to follow a certain pattern
that every email has, so we are going to use a regex expression to do this and set up a message
if the email doesn´t follow the pattern established by this expression. We add an error property to the CssTextField
that this changes the colour to red if there is an error message to show about this field.
// ...
<CssTextField
name='email'
label='Email Address'
variant='outlined'
margin='normal'
inputRef={register({
required: 'You must provide the email address!',
pattern: {
value: /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
message: 'You must provide a valid email address!',
},
})}
autoComplete='email'
error={!!errors.email}
className={classes.margin}
fullWidth
autoFocus
/>
// ...
Now, we want that if occurs any of the errors aforementioned (required field and pattern) to show the message to the user. We use this code after the previous component:
{errors.email && (
<span className={classes.error}>{errors.email.message}</span>
)}
// ...
비밀번호 필드
In the password field we are going to set up as a required field and as the minimum length of 6 characters. The component with the register function and the error message display section will be like this:
// ...
<CssTextField
name='password'
label='Password'
type='password'
variant='outlined'
margin='normal'
inputRef={register({
required: 'You must provide a password.',
minLength: {
value: 6,
message: 'Your password must be greater than 6 characters',
},
})}
fullWidth
autoComplete='current-password'
/>
{errors.password && (
<span className={classes.error}>{errors.password.message}</span>
)}
// ...
체크박스
For Checkbox
component, there are two options. However, I prefer the second one which the defaultValue updates the initial state of the checkbox. This are the options:
옵션 1 - 등록
This option is using the register function like in the previous components.
// ...
<FormControlLabel
label='Remember me'
name='remember'
control={
<Checkbox
className={classes.checkBox}
inputRef={register()}
/>
}
/>
// ...
옵션 2 - 컨트롤러 및 렌더링
In this option, we need to change the Checkbox to Controller inside the control property to be able to expose to register this field in the form data. In the Controller
component we add the control={control}
we put a defaultValue
right in line, and add the render property to set up the onChange event and checked value.
After the previous grid container, we add another one to add the checkTest
checkbox. You can see the component added into the code below:
// ...
</Grid>
<Grid container>
<FormControlLabel
control={
<Controller
control={control}
name='checkTest'
defaultValue={true}
render={({ onChange, value }) => (
<Checkbox
className={classes.checkBox}
onChange={e => onChange(e.target.checked)}
checked={value}
/>
)}
/>
}
label='Checkbox with Controller and render'
/>
</Grid>
<Button
// ...
Now that we have all in place let's test it out.
React-Hook-Form의 DevTools
- To install the devtools in the dev dependencies package in the project executing the following command:
yarn add @hookform/[email protected] -D
The latest version at this time is 2.2.1
.
- import the
DevTool
in theSignInForm
Component:
import { DevTool } from '@hookform/devtools';
- We have already the control object in the useForm declaration:
const { register, handleSubmit, watch, control, errors } = useForm();
- After the Container component we add the DevTool:
// ...
return (
<Container component='main' maxWidth='xs'>
<DevTool control={control} />
// ...
That's it. You will see the dev tools on the browser as soon as it renders again after you save the file.
참고문헌
Reference
이 문제에 관하여(멋진 React Hook Form과 Material-UI Libraries를 사용한 React의 궁극적인 형식 검증!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sergiosanchezs/ultimate-form-validation-in-react-with-the-awesome-react-hook-form-and-material-ui-libraries-26ii텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)