react-hook-form 라이브러리를 접하게 되면서 장점 중 하나가 re-rendering이 적다는 것이었다. 이해하기 위해서는 controlled component, uncontrolled component 개념을 알게되었다. 입력을 받는 방법중 여러 입력을 다루는 form을 대표적이 예시로 내용을 작성하였다.
<form onSubmit={handleSubmit}>
<input type="text" value={name} onChange={(e)=>setName(e.target.value)}/>
</form>
controlled component
의 대표적인 예시이다.class Form extends Component {
constructor() {
super();
this.state = {
name: "",
};
}
handleNameChange = (event) => {
this.setState({ name: event.target.value });
};
render() {
return (
<div>
<input type="text" value={this.state.name} onChange={this.handleNameChange} />
</div>
);
}
흐름을 살펴보면,
''
빈 비열로 시작a
입력, handleNameChange가 호출을 받는다. a
를 받고 setState를 부른다. input은 받은 a
를 value로 가지고 re-render이 된다.b
를 입력하면 handleNameChange가 호출을 받는다. ab
를 가져와서 seState로 상태를 저장한다. input을 ab
value를 가지고 re-render 된다. 이러한 흐름은 input의 value가 바뀔때 마다 값을 push
하기 때문에 요청할 필요없이 구성요소가 항상 현재 값을 갖게된다. 데이터와 입력은 항상 동기화된다.
input뿐 아니라 다른 controlled component가 있다.
ref
를 이용해 DOM에 접근한다.const NameForm = () => {
const inputRef = useRef<HTMLInputElement>(null);
function handleSubmit(event) {
alert('A name was submitted: ' + inputRef.current.value);
}
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" ref={inputRef} />
</label>
<input type="submit" value="Submit" />
</form>
)
}
pull
하는 방식이다. 여기까지 두 component의 특징을 이해했다면 하단에 나올 react-hook-compont의 특징을 좀더 이해하기 쉬울 것 같다.
react-hook-form은 Uncontrolled component의 방식을 활용한 라이브러리이다.
유명한 form 라이브러리중 하나인 formik과 비교한 표.
1. 간결한 코드 (regster,watch 등의 기능을 통해 코드양을 줄일 수 있다.)
2. 적은 용량
3. 자식 컴포넌트 리렌더링 방지 (uncontrolled component의 특징)
4. 렌더링 최소화 (uncontrolled component의 특징2)
5. 빠른 마운트 속도
import { useState } from "react";
import { useForm } from "react-hook-form";
import Header from "./Header";
export function App() {
const { register, handleSubmit } = useForm();
const [data, setData] = useState("");
return (
<form onSubmit={handleSubmit((data) => setData(JSON.stringify(data)))}>
<Header />
<input {...register("firstName")} placeholder="First name" />
<select {...register("category")}>
<option value="">Select...</option>
<option value="A">Option A</option>
<option value="B">Option B</option>
</select>
<textarea {...register("aboutYou")} placeholder="About you" />
<p>{data}</p>
<input type="submit" />
</form>
);
}
위의 개념을 알기 전 장점을 읽었을 때는 와닿지않았다. 하지만 component의 개념을 이해하고 다시 장점을 읽으니 라이브러리의 필요성 및 내세우는 장점의 이유를 알 수 있었다.
사이프 프로젝트에서 select
, input
, textarea
, file
의 데이터를 받아야 하는 기능에 react-hook-form을 적용해봤다.
setValue,watch 기능을 추가로 사용하였다.
특히 이미지 부분에서 많은 시간이 들었다. 이미지가 들어간 배열을 watch로 관찰하고 setValue로 자식 컴포넌트의 값을 받아 반영시켜주었다,
<ImageLayout>
{Array.from({ length: 5 }).map((item, idx) => {
return (
<AddCommunityImage
ref={inputRef}
key={idx}
pk={idx}
data={watchUploadImages[idx]}
imageList={watchUploadImages}
dispatch={(v: Image[]) => setValue("uploadImages", v)}
/>
);
})}
</ImageLayout>
완료 버튼을 누르면 입력한 데이터들이 key : value로 묶여 나온걸 확인할 수 있다.
https://so-so.dev/react/form-handling/
https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/
https://mysterico.tistory.com/9
https://soldonii.tistory.com/145