반복성을 줄인다.
login, 회원가입 등의 일을 하게 될때 input창에 입력데이터를 집어넣고 입력창의 변화를 감지해서 값을 저장해 줘야한다 -> useState와 onChange 함수의 사용이 굉장히 많아짐 -> 코드의 길이가 늘어나고 비슷한 코드 반복
input창에 여러 조건을 줄 수 있다.
코드가 훨씬 짧아진다 가독성이 증가한다.
렌더링 상태, 에러 등의 관리가 쉬워진다.
input태그에 직접 사용하는 방식은 아래의 웹사이트를 참고하면 된다.
특히 오픈소스 컨설팅의 글은 매우 상세하게 나와있으니 꼭 읽어보자
https://tech.osci.kr/introduce-react-hook-form/
https://www.daleseo.com/react-hook-form/
component에 활용하는 법도 오픈소스 컨설팅에서 잘 알려준다! 거기다 mui를 사용하는법까지
https://tech.osci.kr/react-hook-form-with-mui/
오픈 소스 컨설팅의 글을 내 프로젝트에 적용해서 정리해서 써보도록 하겠다.
아이디 입력창을 만들어 활용해 보자
컴포넌트를 만들어 react-hook-form을 사용하기 위해서는 useController를 사용해야한다.
import styled from 'styled-components';
import { AiOutlineUser } from 'react-icons/ai';
import {
Control,
FieldPath,
FieldValues,
RegisterOptions,
useController,
} from 'react-hook-form';
코드를 쓰면서 자동으로 import하는 것이 좋다!!
styledinput에 입력되는 값들의 타입을 정해줘야한다!!
export type TControl<T extends FieldValues> = {
placeholder?: string;
style?: React.CSSProperties;
className?: string;
control: Control<T>;
name: FieldPath<T>;
rules?: Omit<
RegisterOptions<T>,
'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'
>;
};
const InputContainer = styled.div` //input 태그를 감쌀 컨테이너
display: flex;
align-items: center;
width: 17.125rem;
height: 4rem;
background-color: #fff6ec;
`;
const StyledInput = styled.input` // input 입력창
background-color: #fff6ec;
padding-left: 2rem;
border: none; /* 입력란 테두리 제거 */
outline: none; /* 입력란 포커스 시 외곽선 제거 */
color: #7d7b7b;
font-weight: bold;
`;
const Icon = styled(AiOutlineUser)` // 사람 아이콘 추가!
font-size: 1.5rem;
flex-shrink: 0;
color: #7d7b7b;
margin-left: 10px;
height: 7rem;
weight: 7rem;
`;
React.FC<TControl>에 1형식값이 필요하기 때문에 any를 넣었다.
어떤 타입인지 감이 안잡혀서 any를 넣었는데 더 좋은 타입이 있다면 댓글로 알려주시면 감사하겠습니다.
const StyledIdInputIcon: React.FC<TControl<any>> = ({
className,
placeholder,
style,
name,
rules,
control,
}) => {
const {
field: { value, onChange },
} = useController({ name, rules, control });
return (
<InputContainer>
<Icon />
<StyledInput
className={className}
placeholder={placeholder}
value={value}
onChange={onChange}
style={style}
/>
</InputContainer>
);
};
export default StyledIdInputIcon;
className - class설정하기 위해서
placeholder - 기본 입력창에 보여주기 위한것
style - 인라인 css
name - 일반 react-hook-form에서 {...register('여기 들어가는 값', ~~)}
rules - {...register("email",여기에 들어가는 값)} pattern, required 같은 값들이 들어감
ex) 이메일 형식 지정, 이메일 입력 필수값 지정 등
control - 기본 입력 값들
const {
field: { value, onChange },
} = useController({ name, rules, control });
field를 value와 onChange로 나눠주고 name, rules, control을 useController에 있는 것으로 바꿔주기
여기서 value와 onChange는 기존 input에서 사용하는 것과 똑같은 의미로 사용됨
즉 value는 input창의 값을 뜻하고 onChange는 input창의 값이 바뀌는 것을 의미
return (
<InputContainer>
<Icon />
<StyledInput
className={className}
placeholder={placeholder}
value={value}
onChange={onChange}
style={style}
/>
</InputContainer>
);
컴포넌트 만드는 것은 끝났으니 컴포넌트를 페이지에서 활용해보자
interface IForm {
email: string;
}
const {
register,
formState: { errors, isSubmitting, isSubmitted },
handleSubmit,
control,
} = useForm<IForm>({
mode: 'onSubmit',
defaultValues: {
email: '',
},
});
const handleLogin: SubmitHandler<IForm> = (data) => {
// 여기에 api axios보내는 것을 쓰면됨
};
기본 input태그에서 사용하는것과 거의 똑같다 단!! control이 추가되는 차이가 있다.
<form onSubmit={handleSubmit(handleLogin)}> // 제출 버튼 눌러주면 handleLogin을 실행하겠다.
<div className={classes.inputContainer}> //class이름 정해주기
{errors.email && ( //에러의 이메일 값이 존재하면 email에 메시지를 띄워준다.
<small role="alert" style={{ color: 'red', fontSize: '10px' }}>
{errors.email.message}
</small>
)}
<StyledIdInputIcon
name="email" // 필드의 이름
placeholder="이메일" // placeholder
control={control} // useForm에서 가져온 control
rules={{ //register에 등록하는 패턴, required같은 조건들
pattern: {
value:
/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i,
message: '이메일 형식에 맞지 않습니다.', //pattern이 맞지 않을시 출력할 message
},
}}
/>
</form>
위의 방식대로 사용하면 된다.
이렇게 사용하면 email에 값이 input창이 바뀔때마다 인식해서 email값이 들어간다.
이렇게 자기가 원하는 input창을 만들어서 react-hook-form을 활용해 간단하게 axios보내보자!!!!
제가 쓴 글 참고해주셨네요~! 감사합니다!!
오늘도 행복한 하루 보내세요 :)