Hello creators ๐
[_INTRO_] RFH ์ ์ฒ์ ํน์ ๋ค์ ๊ณต๋ถํ๋ค๋ฉด ๋ด์ผ ํ๋ ๊ฒ๋ค ๋ณธ๋ฌธ
[ํ๋ก ํธ์๋(FE) ๊ฐ๋ฐ] (feat. ์ฃผ๋์ด)/React Hook Form
[_INTRO_] RFH ์ ์ฒ์ ํน์ ๋ค์ ๊ณต๋ถํ๋ค๋ฉด ๋ด์ผ ํ๋ ๊ฒ๋ค
๋ถ์๋งค๋_HA 2024. 12. 1. 23:07728x90
๋ฐ์ํ
RHF ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋, ๊ธฐ๋ณธ ์ง์์ผ๋ก ์๋ฉด, ๋์์ด ๋๋ ๊ฒ๋ค
- ๋ฐ๋์ 'C:\Users\nextinnovation\Desktop\DJ-DEV\dev_notes\Hard skills\React Hook Form\3_์ ์ด ์ปดํฌ๋ํธ์ ๋น์ ์ด ์ปดํฌ๋ํธ(์ฐํ ์ฝ).md' ๋ฅผ ๊ณต๋ถํ๊ณ ์ฌ ๊ฒ
- ๋น์ ์ด ์ปดํฌ๋ํธ๊ฐ ๋ฌด์ ์ธ์ง
- react hook form ์ด ๋น์ ์ด ์ปดํฌ๋ํธ์ ๋จ์ ์ ์ด๋ป๊ฒ subscribe ๊ธฐ๋ฅ์ ํตํด ๊ทน๋ณตํ๋์ง์ ๋ํ ๋งฅ๋ฝ์ ์๊ณ ์์ด์ผ ํจ
๋ณต์ต ์์ (241120 ์์ฑ)
1. input, select, textarea ๋ก HTML ์ ์์ฑํ๋ค. ๋ฒํผ์ ํด๋ฆญํ์ ๋, submit ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ฒ ๋๋๋ฐ, ๊ทธ์ ๋ฐ๋ผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ input, select, textarea ์ ๊ฐ์ ์ถ๋ ฅํ๋ ์ฝ๋๋ฅผ ์ดํด๋ณด๋๋ก. ( ์ถ์ฒ : Hard skills\React Hook Form\3_์ ์ด ์ปดํฌ๋ํธ์ ๋น์ ์ด ์ปดํฌ๋ํธ(์ฐํ ์ฝ).md)
- ์ฌ๊ธฐ์ ์ถ๊ฐ๋ก ์ฐ๋ ๊ฒ ๋ณด๋ค, ์ ํ์ผ๋ก ๊ฐ์, ๋ค์ ๋ณต์ตํ๋๊ฒ ๋์ ๋ฏ
2. '์ฌ์ฉ์๊ฐ ๊ฐ์ ์ ๋ ฅํ๊ณ -> ์ ๋ ฅํ ๊ฐ์ด DOM ์ผ๋ก PUSH ๋๊ณ -> DOM ์ ์๋ ๊ฐ์ PULL ํด์ค๊ณ -> RENDER ๋๋ ๊ณผ์ '์์ '์ ๋ขฐ ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ' ์ ํ์์ฑ์ด ๋์จ๋ค. (#โญโญโญ ์ ๋ขฐ ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ์ ๊ฐ๋ ์ ๋งํ ์ ์์ด์ผ ํจ)
(์ถ์ฒ : Hard skills\React Hook Form\3_์ ์ด ์ปดํฌ๋ํธ์ ๋น์ ์ด ์ปดํฌ๋ํธ(์ฐํ ์ฝ).md)
3. ๊ทธ๋ฌ๋ฉด, 'form ๋ฐ์ดํฐ๊ฐ ์์ง์ด๋ ํ๋ฆ' ์ค์์, '์ ๋ขฐ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ' ๋ ์ด๋์ธ๊ฐ. (#โญ์ด ํ์์ '๋ฐ์ดํฐ๊ฐ ์์ง์ด๋ ๊ด์ ' ์ผ๋ก ํด์ํ๋ค๋ ๊ฒโญโญ)
๊ทธ๋ฌ๋ฉด, '์ ๋ขฐ ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ' ๋ผ๋ ๊ฒ์ด 'ํ๋์ ์ํ๋ ํ ๊ณณ์ ์์ด์ผ ํ๋ค.' ๋ผ๋ฉด, 'ํ๋์ ์ํ' ๋ ๋ญ์ง? ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ํ๋ '์ด๋์ ์์ง?'
๊ทธ๋ผ ์ฐ์ , '์ํ' ๋ผ๋ ๊ฑด ๋ญ์ง?
4. '์ํ๋?' '์ํ์ ๊ฐ๋ ์ ๋น์ถ์ด๋ดค์ ๋, ์ ๋ขฐ ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ' ๋? '๊ทธ๋ฌ๋ฉด, form ํ๊ทธ์๋ ์ด๋ค ์ํ ๋ค์ด ์๊ณ , ์ด๋์์ ๊ด๋ฆฌ๋๋๊ฐ?' (#์ ํธ๋ฑ ์์)
- ์ผ๋ฐ์ ์ธ ์ ํธ๋ฑ์ ๋นจ๊ฐ, ์ฃผํฉ, ์ด๋ก์ ์์ ํํํ ์ ์๋ค. ๊ฐ๊ฐ ์ ์ง, ์ํ, ํต๊ณผ์ ์๋ฏธ๊ฐ ์์ง.
- ์ ํธ๋ฑ์ 3๊ฐ์ง ๊ฒฝ์ฐ์ ์๋ฅผ ๊ฐ๋๋ค.
- ์ด๋, ์ ํธ๋ฑ์ด '์ค์ ๋ก ์ด๋ก๋ถ' ์ ๋น์ถ๋ฉด, ์ ํธ๋ฑ์ 'ํ๋๋ถ์ ๋น์ถ๋ ์ํ' ๊ฐ ๋๋ค.
- ์ ํธ๋ฑ์ด ํํํ ์ ์๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ 3๊ฐ ์ด๊ณ , ๊ทธ ์ค ํ๋๊ฐ ์ ํ๋์ด, ์ค์ ๋ก ํํ๋ ๊ฒ์ด '์ํ' ๋ค.
(์ถ์ฒ : https://developer.mozilla.org/en-US/docs/Glossary/State_machine)
- ๊ทธ๋ฌ๋ฉด, ์ด ์์คํ
์ด ํํํ๊ณ ์๋ '๋ชจ๋ ์ํ' ๊ฐ ์กด์ฌํ๊ณ ,
- ๊ทธ ์ค ํ๋์ ์ํ๊ฐ ๋๋ฉด, ๊ทธ ์ํ์ ๋ํ ๊ฐ์, 'ํ ๊ณณ' ๋ง ๊ธฐ์ตํ๋ค! ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค. (#โญโญโญโญโญโญ)
- form ํ๊ทธ์ ์์์ผ๋ก input, select, textarea ๋ฑ์ด ์ฌ ์ ์๋ค.
- ์ด์ , input ํ๊ทธ ์๋ง ์ง์คํ๋ค๋ฉด, input ํ๊ทธ์ ์ํ๋, value ์์ ๋ด๊ธด ๊ฐ์ด ๋๋๊ฒ ๋ง์ง ์์๊น? ์๋๋ฉด, input ํ๊ทธ๊ฐ ๊ฐ์ง ์ ์๋ ๊ฒฝ์ฐ์ ์ ์ค ํ๋์ ๊ฒฝ์ฐ๊ฐ ๋ค์ด์จ ๊ฑฐ๋๊น.
- ๊ทธ๋ฆฌ๊ณ ์ด '์ํ' (value) ๋, value attribute ๋ก ๋ค์ด๊ฐ๊ณ -> value attribute ๋ DOM ์์ ์์ผ๋๊น, DOM ์ push ๊ฐ ๋๋ค.
- ๊ทธ๋ฌ๋ฉด ๊ฐ์ ๊ฐ์ ธ์ฌ ๋๋, DOM ์์ PULL ์ ํตํด ์ต์ ํ ํ๊ฒ ๋๋ค.
CF. FORM ๊ณผ ๊ด๋ จ๋ ์ผ๋ จ์ ๊ณผ์ ์ STATE MACHINE ๊ด์ ์์ ๋ณธ๋ค๋ฉด
- ์ด๊ฒ๋ค์ด ๊ฐ์ง ์ ์๋ '์ํ' ๋ก๋
1) ๋๊ธฐ์ค (์๋ฌด๊ฒ๋ ์์ฑ ์ ๋๋ ์ํ)
2) ์์ฑ์ค์ธ ์ํ
3) ์์ฑ ์๋ฃ๋ฅผ ํด๋ฆญํ ์ํ
4) ์์ฑ ๊ฒฐ๊ณผ๋ฌผ์ด ์ ํจํ์ง ํ์ธํ๋ ์ ํ ๊ณผ์ (transition)
5) ์ ์ถ ์ฑ๊ณต ๋๋ ์คํจ์ ์ํ
- ์คํจ์ ๊ฒฝ์ฐ, ๋ค์ ์์ฑํ๋ ํ์ด์ง๋ก ์ด๋ํ๊ฒ ๋จ
- ๊ทธ๋ฌ๋ฉด, ์์ ์์ฑํ ๋ค์ํ ์ํ๋ ๋ญ๊น? form ์ ์ถ ๊ณผ์ ์์ ์ฌ์ฉ์ ํ๋ฆ? ์ฌ์ฉ์์ ์ํ? ๋ผ๊ณ ๋ด์ผ ํ ๊น? ๊ทธ๋ฆฌ๊ณ ๊ฐ ๊ณผ์ ์ ์ปจํธ๋กค ํ๋ค๊ณ ์๊ฐํด์ผ ํ ๊น?
stateDiagram-v2
state "๋๊ธฐ (Waiting)" as Waiting
state "์์ฑ ์ค (In Progress)" as InProgress
state "์ ์ถ (Submission)" as Submission
state "์ ์ถ ์คํจ (Submission Failure)" as SubmissionFailure
state "์ ์ถ ์ฑ๊ณต (Submission Success)" as SubmissionSuccess
state "๋ค์ ํ์ด์ง (Next Page)" as NextPage
Waiting --> InProgress : Start writing
InProgress --> Submission : Click Submit
Submission --> SubmissionFailure : Validation Failed
Submission --> SubmissionSuccess : Validation Passed
SubmissionFailure --> InProgress : Retry
SubmissionSuccess --> NextPage : Proceed
5. ๊ทธ๋ฌ๋ฉด React Hook Form ์ '์ ๋ขฐ ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ' ๋?
- '์ ๋ขฐ ๊ฐ๋ฅํ ๋จ์ผ ์ถ์ฒ' ๋ 'ํ๋์ ์ํ๋ ํ ๊ณณ' ์๋ง ์์ด์ผ ํ๋ค๋ ์๋ฏธ ์ด๋ค.
- React ๋ value ์ ๊ฒฐํฉ๋ useState ์ state ๋ฅผ 'Single Source of Truth' ๋ก ์ฌ์ฉํ์ง๋ง
- state ๋ก ๋ณด๋ ์ด์ ๋, form ์ ์ถ์ STATE MACHINE ๊ด์ ์์ ๋ณผ ๋, '์์ฑ' ๋จ๊ณ ๋ค์ '์ ์ถ' ์ธ๋ฐ, ์ด๋, validation ๊ฒ์ฌ๋ฅผ ํ ๋, state ์์ ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ๋ณผ ์๋ ์์ง ์์๊น. (#โญโญโญโญโญ)
(๋ฌผ๋ก , ๊ทธ๋ฅ, ๋จ์ํ๊ฒ, react ์ useState ์ state ๋ผ๊ณ ๋ ํ๊ธด ํ๋๋ฐ...)
- React Hook Form ์ DOM ์ ๊ฐ์ push ํ๊ณ , ํด๋น ํ๊ทธ์ ๊ฐ์ด ํ์ํ๋ฉด, DOM ์์ ๊ฐ์ PULL ํด์จ๋ค.
- DOM ์ PUSH ํ๋ ์๋ฆฌ๋, input ํ๊ทธ ๋ณธ์ฐ์ push ๋ก์ง์ ๋ฐ๋ฅธ๋ค.
- DOM ์์ PULL ํ๋ ์๋ฆฌ๋ react ์ useRef ๋ฅผ ์ฌ์ฉํ์ฌ DOM ์ ์๋ ๊ฐ์ PULL ํด์จ๋ค.
- input ์ ๋ฃ์ ๊ฐ์ด ํ์ํ ์๊ฐ์, submission or validation. ์ด๋, DOM ์์ ๊ฐ์ PULL ํด์จ๋ค. (#โญโญโญโญโญ form ๊ณผ์ ์ STATE MACHINE ๊ด์ ์ผ๋ก ๋ณด๊ณ , ์ด๋์์ PULL ํด์ค๋๊ฐ๋ฅผ ์ค์ฌ์ผ๋ก ์๊ฐํด๋ณด๋ฉด ๋๋ค!!!)
- ๊ทธ๋ฌ๋ฉด, ๊ฐ ์ํ ๋ฐ ์ ์ด(transition) ๊ณผ์ ์ react hook form ์ด ์ด๋ป๊ฒ ๊ด๋ฆฌํ๋์ง๊ฐ ๋์จ๋ค.
6. FORM ์ฌ์ฉ์ ํ๋ฆ์ STATE MACHINE ๊ด์ ์์ ๋ฐ๋ผ๋ณด๊ณ , ๊ฐ STATE ๋ฐ Transition ์ react hook form ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ
stateDiagram-v2
state "๋๊ธฐ (Waiting)" as Waiting
state "์์ฑ ์ค (In Progress)" as InProgress
state "์ ์ถ (Submission)" as Submission
state "์ ์ถ ์คํจ (Submission Failure)" as SubmissionFailure
state "์ ์ถ ์ฑ๊ณต (Submission Success)" as SubmissionSuccess
state "๋ค์ ํ์ด์ง (Next Page)" as NextPage
Waiting --> InProgress : Start writing
InProgress --> Submission : Click Submit
Submission --> SubmissionFailure : Validation Failed
Submission --> SubmissionSuccess : Validation Passed
SubmissionFailure --> InProgress : Retry
SubmissionSuccess --> NextPage : Proceed
WAITING ์ํ
- ํด๋น ์ํ์์ ๋ฒ์ด์ง๋ ์ผ :
Inputs are idle, and no user interaction has occurred.
- RHF Role:
Initialize the form with defaultValues.
const { register, handleSubmit } = useForm({
defaultValues: { username: '', email: '' },
});
InProgress ์ํ
- What Happens:
The user starts typing or interacting with the form.
- RHF Role:
Track input values in the DOM (uncontrolled components).
<input {...register('username')} />
Submission ์ ์ถ
- What Happens:
The user clicks the submit button, and RHF pulls values from the DOM.
- RHF Role:
handleSubmit is triggered, and RHF retrieves values via useRef.
const onSubmit = (data) => {
console.log(data); // Data is pulled from the DOM
};
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('username')} />
<button type="submit">Submit</button>
</form>
Submission Failure:
- What Happens:
Validation fails due to incorrect or missing values.
- RHF Role:
Perform validation using rules passed to register.
Error states are managed in formState.errors.
<input
{...register('email', { required: 'Email is required' })}
/>
{formState.errors.email && <p>{formState.errors.email.message}</p>}
Submission Success
- What Happens:
Validation passes, and the form is submitted successfully.
- RHF Role:
Proceed with the form submission logic in the onSubmit callback.
const onSubmit = async (data) => {
// Handle API submission here
console.log('Submission Successful', data);
};
Next Page
- What Happens:
After successful submission, the user navigates to the next page.
- RHF Role:
Redirect or reset the form using RHF utilities like reset().
const { reset } = useForm();
const onSubmit = (data) => {
console.log(data);
reset(); // Reset the form after successful submission
};
์ ์ฒด flow
import React from 'react';
import { useForm } from 'react-hook-form';
function FormExample() {
const {
register,
handleSubmit,
formState: { errors },
reset,
} = useForm({
defaultValues: { username: '', email: '' },
});
const onSubmit = async (data) => {
try {
console.log('Validation Passed:', data);
// Simulate successful submission
reset();
} catch (err) {
console.error('Submission Failed:', err);
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>Username</label>
<input {...register('username', { required: 'Username is required' })} />
{errors.username && <p>{errors.username.message}</p>}
</div>
<div>
<label>Email</label>
<input {...register('email', { required: 'Email is required' })} />
{errors.email && <p>{errors.email.message}</p>}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default FormExample;
7. ์ด๋ฌํ ํ๋ฆ์์ REACT HOOK FORM ๊ฐ์๋ฅผ ์ด๋ป๊ฒ ๋ค์ ๊ฒ ์ธ๊ฐ
- ์์ ์ด๋ก ์ ์ธ ๋ถ๋ถ์ด ์ฝ๋์ ๊ตฌ์ฒด์ ์ผ๋ก ์ด๋ป๊ฒ ๊ตฌํ์ด ๋๋๊ฐ! ๋ฅผ ์ฐ๊ฒฐํ๊ธฐ
- ์ฝ๋๋ฅผ ์ฝ์ผ๋ฉด์ ํด๋น ๋ถ๋ถ์ ๋ํด ์ฃผ์ ๋ฌ๊ธฐ
- ์ธ์ธํ ๋ฌธ๋ฒ์ ์ธ ๊ตฌํ์ฒด๋ฅผ ์ดํดํด์ผ ํจ
ex) {...register('customer')} ์์ ... ์ด๋ ๊ฒ ํผ์ณ์ฃผ๋ ์ด์ ๊ฐ ๋ฌด์์ธ์ง
8. ์ง๊ธ๊น์ง ์ดํดํ ๋ถ๋ถ ์ฃผ์ ๋ฌ๊ธฐ
import React from 'react';
import { useForm } from 'react-hook-form';
function FormExample() {
const {
register,
/* [register ๋ฉ์๋]
1) parameter
2) return
- name, onBlur, onChange, ref ๋ฅผ return ํ๋ค.
- ์ด๊ฒ spread operator ๋ก ํ๋ฆฌ๋ฉด์ input ์ ์์ฑ์ ๋ถ๊ฒ ๋๋ค.
*/
handleSubmit,
/* handleSubmit
- ์ ์ถ ํ์ ๋์ ์ํ๋ฅผ ์ฒ๋ฆฌ ํ๋ค.
*/
formState: { errors }, // ์๋ฌ ์ํ ์ฒ๋ฆฌ
reset, // ์ด๊ฑด?
} = useForm({
defaultValues: { username: '', email: '' },
});
const onSubmit = async (data) => {
try {
console.log('Validation Passed:', data);
// Simulate successful submission
reset();
} catch (err) {
console.error('Submission Failed:', err);
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>Username</label>
<input {...register('username', { required: 'Username is required' })} />
{errors.username && <p>{errors.username.message}</p>}
</div>
<div>
<label>Email</label>
<input {...register('email', { required: 'Email is required' })} />
{errors.email && <p>{errors.email.message}</p>}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default FormExample;
9. ์ถ๊ฐ๋ก ์๊ณ ์ถ์ ๊ฒ
1. STATE MACHINE ์ ๊ทธ๋ฆฌ๊ณ - ๊ฐ ๊ด๋ฆฌ ํฌ์ธํธ๋ฅผ ๋ค์ ์๊ฐํด๋ณด๊ธฐ
2. ๋ฐ์ดํฐ๋ฅผ ์ด๋์์ ๊ฐ์ ธ์์ผ ํ๋์ง๋ฅผ, ๋ค์ด์ด๊ทธ๋จ์ผ๋ก ์ด์ผ ๊ทธ๋ ค์ผ ํ๋์ง ์๊ฐํด๋ณด๊ธฐ
3. react hook form ๊ฐ์๋ฅผ ๋ค์ผ๋ฉด์, ๊ทธ๊ฒ ๋๋ก์ ํ๋ฆ์ ์ ์ด๋ณด๋ฉด ์ข์ ๊ฑฐ ๊ฐ์๋ฐ.
- ์ด๊ฒ ๋ค๋ฅธ ๊ณต์ ๋ฌธ์๋ฅผ ๋ณผ ๋๋ ๋น์ทํ๊ฒ ์ด ๋ฐฉ์์ด ์ ์ฉ๋ ์ ์์ ๊ฒ
728x90
๋ฐ์ํ
'[ํ๋ก ํธ์๋(FE) ๊ฐ๋ฐ] (feat. ์ฃผ๋์ด) > React Hook Form' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
1_normal form (#์ผ๋ฐ FORM ์ React Hook fom ๋น๊ต) (1) | 2024.12.01 |
---|
Comments