폼 라이브러리를 사용하면 더이상 노가다성 코딩을 하지 않아도 됨.
검증을 대신해주는 폼, state를 대신해주는 폼( react-form, redux-form, react-hook-form, formik) 등 종류가 다양하다
✅ react-hook-form의 장점
state 입력할때마다 리렌더링 -> 불필요한 렌더링이 지속적으로 일어나 비효율적이며 느림.
react-hook-form은 input의 값을 실시간으로 state에 반영하는것이 아닌 등록함수가 실행 될 때 불필요한 렌더링이 제거되고 한번에 바꿔 처리(렌더링) 하기 때문에 빠르고 효율적이다.
이렇게 처리하는 방식을 비제어 컴포넌트라고 하는데, 리액트 hook 폼은 비제어 컴포넌트이다.
❗️주의❗️
default가 비제어 컴포넌트 방식일 뿐이다.
mode에 onChange를 사용해 제어 컴포넌트로 사용하려면 사용할 수 있다.
✅ 비제어 컴포넌트(uncontrolled) vs 제어(controlled) 컴포넌트
- 비제어 컴포넌트 : 바닐라 자바스크립트 처럼 sumit함수를 실행할 때 ref 로 input값을 한번에 변경
- 제어 컴포넌트 : 사용자의 입력을 기반으로 state를 실시간으로 관리(setState 사용). 입력이 될 때마다 state값이 실시간으로 변경
중요한 데이터를 저장하고 있다면 제어 컴포넌트를 이용하고,
아니라면 비제어 컴포넌트를 이용해서 성능을 높여주는게 더 좋다.✅ 설치명령어
- npm :
npm install react-hook-form
- yarn :
yarn add react-hook-form
- 사이트
https://react-hook-form.com/get-started/
https://www.npmjs.com/package/react-hook-form
✅ form태그의 button type
<form onSubmit={나의함수}> <button>기본 type값은 submit, 나의함수 실행!</button> <button type="submit">나의함수 실행!</button> <button type="button" onClick={장바구니담기함수}>장바구니담기 실행하는방법</button> <button type="reset">안에 input 지우기!</button> </form>;
- reset : form 내부의 input 값이 모두 삭제
- submit : form 내부의 input 값이 백엔드로 보내진다 → 기본값
- button : 나만의 버튼을 만들고 싶을때 사용
✅ form 태그 적용하기
- index.tsx
import { useForm } from "react-hook-form"; import { wrapFormFunc } from "../../../src/commons/libraries/asyncFunc"; interface IFormData { writer: string; title: string; contents: string; boardAddress: { addressDetail: string; }; } export default function GraphqlMutationPage(): JSX.Element { const { register, handleSubmit } = useForm<IFormData>(); const onClickSubmit = (data: IFormData): void => { console.log(data); // data.boardAddress.addressDetail }; return ( <form onSubmit={wrapFormFunc(handleSubmit(onClickSubmit))}> 작성자: <input type="text" {...register("writer")} /> 제목: <input type="text" {...register("title")} /> 내용: <input type="text" {...register("contents")} /> 주소: <input type="text" {...register("boardAddress.addressDetail")} /> <button>Graphql-API 요청하기</button> </form> ); }
기존코드에 비해 확연하게 줄은걸 볼 수 있음.
form태그에서 onSubmit을 실행하면
페이지이동하려는 습성을 가지고 있다.주소가 바뀌면서 새로고침됨.
해결해줘야 하는데
기본기능을 막아줘야 함!
이벤트안의 기본기능을 막아줘야 한다.//form을 위한 wrapFormAsync export const wrapFormAsync = (asyncFunc: () => Promise<void>) => (event: FormEvent<HTMLFormElement>) => { event.preventDefault(); //기본기능막기 void asyncFunc(); };