[TIL/React-Hook-Form] 2024/07/09
reference:1) https://www.react-hook-form.com/api/usecontroller/controller2) https://legacy.reactjs.org/docs/render-props.html✅ React-Hook-Fo
reference: 1) https://www.react-hook-form.com/api/usecontroller/controller 2) https://legacy.reactjs.org/docs/render-props.html
✅ React-Hook-Form 공식문서 톺아보기
6. Integrating with UI libraries ✍️
import Select from "react-select";
import { useForm, Controller } from "react-hook-form";
import Input from "@material-ui/core/Input";
const App = () => {
const { control, handleSubmit } = useForm({
defaultValues: {
firstName: '',
select: {}
}
});
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="firstName"
control={control}
render={({ field }) => <Input {...field} />}
/>
<Controller
name="select"
control={control}
render={({ field }) => <Select
{...field}
options={[
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
]}
/>}
/>
<input type="submit" />
</form>
);
};외부 UI 라이브러리와 React Hook Form을 어떻게 통합해야 하는지 설명하는 section이다.
Controller 컴포넌트를 사용하면, 외부 UI 라이브러리의 요소의 registration process를 잘 수행할 수 있다고 설명하고 있다.
아래의 코드가 본 section의 핵심이다. 하지만 공식 문서의 Get Started 파트에서는 피상적인 사용법만 다루고 있기에, Controller Component의 더 깊은 내용을 확인해야 했다.

external controlled component와 쉽게 통합하기 위해 사용하는 'Wrapper Component'임을 명시하고 있다.

render props가 핵심인데, render는 컴포넌트에 event와 value를 연결할 수 있는 기능을 제공한다. 자식 컴포넌트에 onChange, onBlur, name, ref, value를 제공하며, 특정 '입력 상태'를 포함하는 fieldState 객체도 제공한다.
render의 type은 'Function'이다. 그런데 ```render={({ field }) => <Input {...field} />}``` 부분이 솔직히 잘 이해가 되지 않았다. 이유를 알아보니, render props가 무엇인지 몰라서 그랬던 것이었다.(React 공식 문서 읽어야 한다는 뜻.)
'render prop'은 함수이고, Controller 컴포넌트에 의해 호출되도록 내부적으로 구현이 되어있다. field 객체를 포함한 다양한 인자를 받을 수 있는 함수인데, 위 코드에서는 field를 구조 분해 할당을 통해 추출한다. 이때, field 객체는 Controller 컴포넌트에 의해 자동으로 제공되는 'form field와 관련된 상태와 메서드'를 포함한다. 이렇게 추출한 field 객체를 하위 컴포넌트(MUI Component 같은)에 전달하여 외부 컴포넌트 요소가 form field의 상태와 상호작용할 수 있게 되는 것이다.

과거 React doc을 살펴보니 커스텀 훅으로 대체되었다고 한다. 예전 공식 문서에서 설명하는 것처럼, render prop은 react 컴포넌트 간에 코드를 공유하기 위한 기법인데, custom hook의 존재 이유와 정확히 일치하기 때문이다. custom hook의 시초 같은 느낌이다.
## 7. Integrating Controlled Inputs ✍️
import { useForm, Controller } from "react-hook-form"; import { TextField, Checkbox } from "@material-ui/core";
function App() { const { handleSubmit, control, reset } = useForm({ defaultValues: { checkbox: false, } }); const onSubmit = data => console.log(data);
return (
); }
계속 공식 문서를 읽다 보니, Controlled component와 Uncontrolled component가 핵심이라는 생각이 든다.
Controlled component는 React의 상태(state)에 의해 값이 제어됨을 의미한다. 한마디로, 사용자가 입력 form을 조작할 때마다 React 상태가 업데이트되며, 이에 따라 UI가 리렌더링 된다는 뜻이다.
이에 반해, Uncontrolled component는 상태에 의존하지 않고 DOM 요소의 ref를 통해 값에 접근한다. 사용자의 입력에 따라 DOM 요소의 값이 변화할지언정, React의 상태는 이를 추적하지 않기에, 렌더링이 일어나지 않아 렌더링을 최적화할 수 있다는 장점을 갖는다.
각각의 장단점이 분명하겠지만, 사용자로부터 많은 정보를 입력받을 경우에는 불필요한 리렌더링을 최적화하는 것이 좋고, 이것이 React Hook Form의 가장 본질적인 컨셉인 것이다.
import React, { useState } from "react"; // React와 useState 훅을 import합니다. import ReactDOM from "react-dom"; // ReactDOM을 import합니다. import { useForm, Controller } from "react-hook-form"; // react-hook-form에서 useForm과 Controller를 import합니다. import Header from "./Header"; // Header 컴포넌트를 import합니다. import ReactDatePicker from "react-datepicker"; // react-datepicker 컴포넌트를 import합니다. import NumberFormat from "react-number-format"; // react-number-format 컴포넌트를 import합니다. import ReactSelect from "react-select"; // react-select 컴포넌트를 import합니다. import Mui from "./Mui"; // Mui 컴포넌트를 import합니다. import ButtonsResult from "./ButtonsResult"; // ButtonsResult 컴포넌트를 import합니다. import DownShift from "./DownShift"; // DownShift 컴포넌트를 import합니다. import AntD from "./AntD"; // AntD 컴포넌트를 import합니다. import DraftExample from "./DraftExample"; // DraftExample 컴포넌트를 import합니다. import { EditorState } from "draft-js"; // draft-js의 EditorState를 import합니다. import InputMask from "react-input-mask"; // react-input-mask 컴포넌트를 import합니다. import Chakra from "./Chakra"; // Chakra 컴포넌트를 import합니다. import "react-datepicker/dist/react-datepicker.css"; // react-datepicker의 CSS 파일을 import합니다. import "antd/dist/antd.css"; // antd의 CSS 파일을 import합니다. import "./styles.css"; // 스타일 CSS 파일을 import합니다.
let renderCount = 0; // 렌더링 횟수를 저장하는 변수를 초기화합니다.
const defaultValues = { Native: "", // Native 입력 필드의 기본값을 설정합니다. TextField: "", // TextField 입력 필드의 기본값을 설정합니다. Select: "", // Select 입력 필드의 기본값을 설정합니다. ReactSelect: { value: "vanilla", label: "Vanilla" }, // ReactSelect 컴포넌트의 기본 선택값을 설정합니다. Checkbox: false, // Checkbox 입력 필드의 기본값을 설정합니다. switch: false, // switch 입력 필드의 기본값을 설정합니다. RadioGroup: "", // RadioGroup 입력 필드의 기본값을 설정합니다. numberFormat: 123456789, // numberFormat 입력 필드의 기본값을 설정합니다. AntdInput: "Test", // AntdInput 입력 필드의 기본값을 설정합니다. AntdCheckbox: true, // AntdCheckbox 입력 필드의 기본값을 설정합니다. AntdSwitch: true, // AntdSwitch 입력 필드의 기본값을 설정합니다. AntdSlider: 20, // AntdSlider 입력 필드의 기본값을 설정합니다. AntdRadio: 1, // AntdRadio 입력 필드의 기본값을 설정합니다. downShift: "apple", // downShift 입력 필드의 기본값을 설정합니다. ReactDatepicker: new Date(), // ReactDatepicker 컴포넌트의 기본 날짜값을 설정합니다. AntdSelect: "", // AntdSelect 입력 필드의 기본값을 설정합니다. DraftJS: EditorState.createEmpty(), // DraftJS 에디터의 기본 상태를 설정합니다. MUIPicker: new Date("2020-08-01T00:00:00"), // MUIPicker 컴포넌트의 기본 날짜값을 설정합니다. country: { code: "AF", label: "Afghanistan", phone: "93" }, // country 객체의 기본값을 설정합니다. ChakraSwitch: true, // ChakraSwitch 입력 필드의 기본값을 설정합니다. reactMaskInput: "" // reactMaskInput 입력 필드의 기본값을 설정합니다. };
function App() { const { handleSubmit, reset, setValue, control } = useForm({ defaultValues }); // useForm 훅을 사용하여 폼 상태를 초기화하고 제어할 수 있는 객체들을 가져옵니다. const [data, setData] = useState(null); // data 상태와 setData 함수를 useState 훅을 통해 초기화합니다. renderCount++; // 렌더링 횟수를 증가시킵니다.
return (
); }const rootElement = document.getElementById("root"); ReactDOM.render(
More to read
프론트엔드와 백엔드 사이
HTTP 상태 코드는 프론트엔드에서 백엔드로 보냈던 요청의 수행 결과를 의미하는 일종의 약속이며, API를 구성하는 핵심 요소 중 하나입니다. 상태 코드와 관련하여, 백엔드는 잘 모르는 프론트엔드의 슬픈 사정이 있습니다.아래는 요청이 실패했음에도, 백엔드에서 상태 코드
JWT토큰 관리 방식 톺아보기
0. 들어가며 🎯 서비스에 접근하려는 사용자가 누구인지 확인하는 과정을 사용자 인증이라고 합니다. 인증된 사용자에게 주어진 권한을 확인하는 작업은 인가라고 부릅니다. 이번 글에서는 인가는 다루지 않습니다. 사용자 인증에는 많은 방식이 있지만, 오늘은 세션 인증 방
A2AA2A / MCP 멀티 에이전트 오케스트레이션
0. 들어가며 ✍️ Google for Developers에, 레스토랑 공급망 시나리오로 엮은 6대 프로토콜(MCP, A2A, UCP, AP2, A2UI, AG-UI)에 대한 가이드가 게시된 이후, MCP와 A2A부터 구현해 보는 것이 좋을 것 같다는 생각이 들었습니