ํฅ์๋ ํผ ์ฒ๋ฆฌ๋ฅผ ์ํ ์๋ก์ด React experimental_useFormStatus ํ ์ ์ดํด๋ณด์ธ์. ๊ธฐ๋ฅ, ์ด์ , ์ฌ์ฉ ์ฌ๋ก ๋ฐ ์์ ๋ฅผ ํตํ ๊ตฌํ ๋ฐฉ๋ฒ์ ์์๋ด ๋๋ค.
React experimental_useFormStatus: ์ข ํฉ ๊ฐ์ด๋
React์ ์งํํ๋ ์ํ๊ณ๋ ๊ฐ๋ฐ์ ๊ฒฝํ๊ณผ ์ ํ๋ฆฌ์ผ์ด์
์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด ์ง์์ ์ผ๋ก ์๋ก์ด ๋๊ตฌ์ API๋ฅผ ๋์
ํฉ๋๋ค. ํ์ฌ ์คํ ๋จ๊ณ์ ์๋ ์ถ๊ฐ ๊ธฐ๋ฅ ์ค ํ๋๊ฐ ๋ฐ๋ก experimental_useFormStatus ํ
์
๋๋ค. ์ด ํ
์ ํนํ ์๋ฒ ์ก์
(server actions)์ ๋ค๋ฃฐ ๋ ํผ ์ ์ถ ์ํ์ ๋ํ ๊ท์คํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋์์๋ experimental_useFormStatus์ ๊ธฐ๋ฅ, ์ด์ ๋ฐ ์ค์ ์ ์ฉ ์ฌ๋ก๋ฅผ ํ๊ตฌํ๋ฉฐ ์์ธํ ์์๋ด
๋๋ค.
experimental_useFormStatus๋ ๋ฌด์์ธ๊ฐ?
experimental_useFormStatus ํ
์ React ์๋ฒ ์ก์
์ ์ฌ์ฉํ์ฌ ์์๋ ํผ ์ ์ถ ์ํ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ปดํฌ๋ํธ๋ ๋ณด๋ฅ(pending), ์ฑ๊ณต ๋๋ ์คํจ์ ๊ฐ์ ํผ ์ ์ถ ํ๋ก์ธ์ค์ ์ฌ๋ฌ ๋จ๊ณ์ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฐ๋ฐ์๊ฐ ๋ ๋ฐ์์ ์ด๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ํผ ๊ฒฝํ์ ๋ง๋ค ์ ์๋๋ก ํด์ค๋๋ค.
๋ณธ์ง์ ์ผ๋ก ์ด ํ ์ ํด๋ผ์ด์ธํธ ์ธก ํผ๊ณผ ์๋ฒ ์ธก ์ก์ ์ฌ์ด์ ๊ฐ๊ทน์ ๋ฉ์ ํผ ์ ์ถ ์ํ๋ฅผ ์ถ์ ํ๊ณ ํ์ํ๋ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋ก๋ฉ ํ์๊ธฐ, ์ฑ๊ณต ๋ฉ์์ง ๋๋ ์ค๋ฅ ์๋ฆผ๊ณผ ๊ฐ์ ์๊ฐ์ ํผ๋๋ฐฑ์ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํ๋ ๋ฐ ํนํ ์ ์ฉํฉ๋๋ค.
experimental_useFormStatus ์ฌ์ฉ์ ์ฃผ์ ์ด์
- ํฅ์๋ ์ฌ์ฉ์ ๊ฒฝํ: ํผ ์ ์ถ ์ํ์ ๋ํ ์ค์๊ฐ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ฌ ์ฌ์ฉ์๊ฐ ์ํฉ์ ์ธ์งํ๊ณ ๊ณ์ ์ฐธ์ฌํ๋๋ก ํฉ๋๋ค.
- ๊ฐ์ํ๋ ํผ ์ฒ๋ฆฌ: ํผ ์ ์ถ ๊ด๋ฆฌ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ํํ์ฌ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ์ค์ ๋๋ค.
- ํฅ์๋ ์ ๊ทผ์ฑ: ๋ณด์กฐ ๊ธฐ์ ์ ์ ๋ฌ๋ ์ ์๋ ์ํ ์ ๋ฐ์ดํธ๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ ๊ฐ๋ฐ์๊ฐ ๋ ์ ๊ทผ์ฑ ๋์ ํผ์ ๋ง๋ค ์ ์๋๋ก ํฉ๋๋ค.
- ๋ ๋์ ์ค๋ฅ ์ฒ๋ฆฌ: ์ค๋ฅ ๊ฐ์ง ๋ฐ ๋ณด๊ณ ๋ฅผ ๋จ์ํํ์ฌ ๋ ๊ฐ๋ ฅํ ํผ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฐ ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ํด๋ฆฐ ์ฝ๋: ํผ ์ ์ถ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์ ์ธ์ ์ด๊ณ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ฌ ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ฝ๊ณ ์ ์ง๋ณด์ํ ์ ์๋๋ก ํฉ๋๋ค.
experimental_useFormStatus์ ๊ตฌ์กฐ ์ดํดํ๊ธฐ
experimental_useFormStatus ํ
์ ์ฌ๋ฌ ์ฃผ์ ์์ฑ์ ํฌํจํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ฌํ ์์ฑ๋ค์ ํผ ์ ์ถ์ ํ์ฌ ์ํ์ ๋ํ ๊ท์คํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ฐ ์์ฑ์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
pending: ํผ ์ ์ถ์ด ํ์ฌ ์งํ ์ค์ธ์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ(boolean) ๊ฐ์ ๋๋ค. ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.data: ํผ ์ ์ถ์ด ์ฑ๊ณตํ์ ๋ ์๋ฒ ์ก์ ์ด ๋ฐํํ ๋ฐ์ดํฐ์ ๋๋ค. ์ก์ ์ ๊ฒฐ๊ณผ๋ก UI๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.error: ํผ ์ ์ถ ์ค์ ๋ฐ์ํ ์ค๋ฅ์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํ๋ ์ค๋ฅ ๊ฐ์ฒด์ ๋๋ค. ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.action: ํผ์ ์ ์ถํ๋ ๋ฐ ์ฌ์ฉ๋ ์๋ฒ ์ก์ ํจ์์ ๋๋ค. ํ์ํ ๊ฒฝ์ฐ ์ก์ ์ ๋ค์ ํธ๋ฆฌ๊ฑฐํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.formState: ์ ์ถ ์ ํผ์ ์ํ์ ๋๋ค. ์ ์ถ ํ๋ก์ธ์ค๊ฐ ์์๋๊ธฐ ์ ์ ํผ์ด ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ์ ์ค๋ ์ท์ ์ ๊ณตํฉ๋๋ค.
๊ธฐ๋ณธ ์ฌ์ฉ ์์
๋ค์์ React ์ปดํฌ๋ํธ์์ experimental_useFormStatus๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ์์ ์
๋๋ค:
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
async function myAction(formData) {
'use server'
// ์ฌ๊ธฐ์ ์๋ฒ ์ธก ๋ก์ง์ ์ํํฉ๋๋ค
await new Promise(resolve => setTimeout(resolve, 2000)); // ์ง์ฐ์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
const name = formData.get('name');
if (!name) {
return { message: '์ด๋ฆ์ ํ์์
๋๋ค.' };
}
return { message: `์๋
ํ์ธ์, ${name}๋!` };
}
function MyForm() {
const { pending, data, error } = useFormStatus();
return (
);
}
export default MyForm;
์ด ์์ ์์ useFormStatus๋ myAction ์๋ฒ ์ก์
์ ์ํด ์์๋ ํผ ์ ์ถ ์ํ๋ฅผ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. pending ์์ฑ์ ์ ์ถ ์ค์ ์
๋ ฅ๊ณผ ๋ฒํผ์ ๋นํ์ฑํํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ, data์ error ์์ฑ์ ๊ฐ๊ฐ ์ฑ๊ณต ๋ฐ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก
๊ธฐ๋ณธ์ ์ธ ํผ ์ ์ถ ์ถ์ ์ ๋์ด, experimental_useFormStatus๋ ๋ ๊ณ ๊ธ ์๋๋ฆฌ์ค์์๋ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๋ช ๊ฐ์ง ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
1. ๋๊ด์ ์ ๋ฐ์ดํธ (Optimistic Updates)
๋๊ด์ ์
๋ฐ์ดํธ๋ ์ฌ์ฉ์๊ฐ ํผ์ ์ ์ถํ ์งํ, ์ ์ถ์ด ์ฑ๊ณตํ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ๊ณ UI๋ฅผ ์ฆ์ ์
๋ฐ์ดํธํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด๊ฐ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. experimental_useFormStatus๋ ํผ ์ ์ถ์ด ์คํจํ ๊ฒฝ์ฐ ๋๊ด์ ์
๋ฐ์ดํธ๋ฅผ ๋๋๋ฆฌ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
import { useState } from 'react';
async function updateProfile(formData) {
'use server'
// ์ง์ฐ์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
await new Promise(resolve => setTimeout(resolve, 2000));
const name = formData.get('name');
if (!name) {
return { success: false, message: '์ด๋ฆ์ ํ์์
๋๋ค.' };
}
return { success: true, message: `${name}๋์ ํ๋กํ์ด ์
๋ฐ์ดํธ๋์์ต๋๋ค!` };
}
function ProfileForm({ initialName }) {
const { pending, data, error } = useFormStatus();
const [name, setName] = useState(initialName);
const handleSubmit = async (e) => {
e.preventDefault();
// ๋๊ด์ ์
๋ฐ์ดํธ
setName(e.target.name.value);
const formData = new FormData(e.target);
const result = await updateProfile(formData);
if (result && !result.success) {
// ์ ์ถ ์คํจ ์ ๋๊ด์ ์
๋ฐ์ดํธ ๋๋๋ฆฌ๊ธฐ
setName(initialName); // ์๋ ๊ฐ์ผ๋ก ๋๋๋ฆฌ๊ธฐ
}
};
return (
);
}
export default ProfileForm;
2. ์กฐ๊ฑด๋ถ ๋ ๋๋ง
experimental_useFormStatus๋ ํผ ์ ์ถ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ UI ์์๋ฅผ ์กฐ๊ฑด๋ถ๋ก ๋ ๋๋งํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ฒ ์ก์
์ ๋ฐํ ๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฉ์์ง๋ UI๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
async function processOrder(formData) {
'use server'
// ์ง์ฐ์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
await new Promise(resolve => setTimeout(resolve, 2000));
const orderId = Math.floor(Math.random() * 1000);
return { orderId };
}
function OrderForm() {
const { pending, data, error } = useFormStatus();
return (
);
}
export default OrderForm;
3. ์ ๊ทผ์ฑ ๊ณ ๋ ค์ฌํญ
์น ๊ฐ๋ฐ์์ ์ ๊ทผ์ฑ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. experimental_useFormStatus๋ฅผ ์ฌ์ฉํ๋ฉด ํผ ์ ๊ทผ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ARIA ์์ฑ์ ์ฌ์ฉํ์ฌ ์คํฌ๋ฆฐ ๋ฆฌ๋์ ํผ ์ ์ถ ์ํ๋ฅผ ์๋ฆด ์ ์์ต๋๋ค.
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
async function submitComment(formData) {
'use server'
await new Promise(resolve => setTimeout(resolve, 2000));
const commentText = formData.get('comment');
if (!commentText) {
return { message: '๋๊ธ์ ํ์์
๋๋ค.' };
}
return { message: '๋๊ธ์ด ์ฑ๊ณต์ ์ผ๋ก ์ ์ถ๋์์ต๋๋ค!' };
}
function CommentForm() {
const { pending, data, error } = useFormStatus();
return (
);
}
export default CommentForm;
์ด ์ค๋ํซ์์ aria-busy={pending}์ ํผ์ด ์ ์ถ ์ค์ผ ๋ ๋ณด์กฐ ๊ธฐ์ ์ ์๋ฆฌ๊ณ , role="alert"์ role="status"๋ ๊ฐ๊ฐ ์ค๋ฅ ๋ฐ ์ฑ๊ณต ๋ฉ์์ง์ ์ ์ ํ ๋ ์ด๋ธ์ ๋ถ์
๋๋ค.
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
experimental_useFormStatus๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํ๋ ํผ์ ๊ฐ๋ฐํ ๋๋ ์ํํ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ฌํญ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค:
- ํ์งํ: ๋ชจ๋ ์ค๋ฅ ๋ฐ ์ฑ๊ณต ๋ฉ์์ง๊ฐ ๋ค๋ฅธ ์ธ์ด์ ๋ง๊ฒ ์ ์ ํ ํ์งํ๋์๋์ง ํ์ธํ์ธ์. ์ฌ๊ธฐ์๋ ๋ฉ์์ง ์์ฒด๋ฅผ ๋ฒ์ญํ๋ ๊ฒ๋ฟ๋ง ์๋๋ผ ๊ฐ ์ธ์ด์ ๊ด๋ก์ ๋ง๊ฒ ๋ฉ์์ง ํ์์ ์กฐ์ ํ๋ ๊ฒ๋ ํฌํจ๋ฉ๋๋ค. ๋ฒ์ญ ๊ด๋ฆฌ๋ฅผ ์ํด
i18next์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ React์ ๋ด์ฅ Context API ์ฌ์ฉ์ ๊ณ ๋ คํ์ธ์. - ๋ ์ง ๋ฐ ์๊ฐ ํ์: ์ ์ธ๊ณ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋ค์ํ ๋ ์ง ๋ฐ ์๊ฐ ํ์์ ์ผ๋์ ๋์ธ์. ๊ฐ ๋ก์ผ์ผ์ ๋ง๊ฒ ๋ ์ง์ ์๊ฐ์ ์ ์ ํ ํ์ํํ๋ ค๋ฉด
date-fns๋moment.js์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ธ์. ์๋ฅผ ๋ค์ด, ๋ฏธ๊ตญ์ MM/DD/YYYY๋ฅผ ์ฌ์ฉํ์ง๋ง ๋ง์ ์ ๋ฝ ๊ตญ๊ฐ๋ DD/MM/YYYY๋ฅผ ์ฌ์ฉํฉ๋๋ค. - ์ซ์ ํ์: ๋ง์ฐฌ๊ฐ์ง๋ก ์ซ์ ํ์๋ ์ง์ญ๋ง๋ค ๋ค๋ฆ
๋๋ค.
Intl.NumberFormatAPI๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ๋ก์ผ์ผ์ ๋ฐ๋ผ ์ซ์๋ฅผ ํ์ํํ์ธ์. ์ฌ๊ธฐ์๋ ์์์ ๊ตฌ๋ถ ๊ธฐํธ, ์ฒ ๋จ์ ๊ตฌ๋ถ ๊ธฐํธ ๋ฐ ํตํ ๊ธฐํธ ์ฒ๋ฆฌ๊ฐ ํฌํจ๋ฉ๋๋ค. - ํตํ ์ฒ๋ฆฌ: ํผ์ด ๊ธ์ต ๊ฑฐ๋๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ ํตํ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ณ ์๋์ง ํ์ธํ์ธ์. ์ ํํ ํตํ ๊ณ์ฐ ๋ฐ ๋ณํ์ ์ํํ๋ ค๋ฉด
currency.js์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ธ์. - ๋ค์ํ ์ฌ์ฉ์๋ฅผ ์ํ ์ ๊ทผ์ฑ: ์ฅ์ ๊ฐ ์๋ ์ฌ๋๋ค๋ ํผ์ ์ฌ์ฉํ ์ ์๋๋ก ์ ๊ทผ์ฑ ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋ฅด์ธ์. ์ฌ๊ธฐ์๋ ์ ์ ํ ARIA ์์ฑ ์ ๊ณต, ์๋งจํฑ HTML ์ฌ์ฉ, ํผ์ด ํค๋ณด๋๋ก ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ๋ณด์ฅํ๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค. ์๊ฐ ์ฅ์ , ์ฒญ๊ฐ ์ฅ์ , ์ธ์ง์ ์ฐจ์ด ๋ฐ ์ด๋ ๋ฅ๋ ฅ ์ ํ์ด ์๋ ์ฌ์ฉ์๋ฅผ ๊ณ ๋ คํ์ธ์.
- ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ: ํนํ ์ธํฐ๋ท ์ฐ๊ฒฐ์ด ๋๋ฆฐ ์ง์ญ์ ์ฌ์ฉ์๋ฅผ ์ํด ์ ์ฌ์ ์ธ ๋คํธ์ํฌ ์ง์ฐ ๋ฌธ์ ๋ฅผ ์ธ์งํ์ธ์. ํผ ์ ์ถ ๊ณผ์ ์์ ๋ก๋ฉ ํ์๊ธฐ๋ ์งํ๋ฅ ํ์์ค๊ณผ ๊ฐ์ ๋ช ํํ ํผ๋๋ฐฑ์ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํ์ธ์.
- ์ค๋ฅ ๋ฉ์์ง์ ๋ช ํ์ฑ: ์ฌ์ฉ์์ ์์น๋ ๊ธฐ์ ์๋ จ๋์ ๊ด๊ณ์์ด ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ๋ฉฐ ์คํ ๊ฐ๋ฅํ๋๋ก ํ์ธ์. ์ ๋ฌธ ์ฉ์ด ์ฌ์ฉ์ ํผํ์ธ์.
- ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น: ์ฐํธ๋ฒํธ ํ์, ์ ํ๋ฒํธ ํ์, ์ฃผ์ ์๊ตฌ์ฌํญ๊ณผ ๊ฐ์ ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น์ ๋ค๋ฅธ ์ง์ญ์ ์์ ๊ด๋ก์ ๋ง๊ฒ ํ์งํํ์ธ์.
์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ํตํฉ
experimental_useFormStatus๋ ๋ค์ํ ์๋ํํฐ ํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํํ๊ฒ ํตํฉ๋์ด ํผ ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๋ช ๊ฐ์ง ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Formik: Formik์ ํผ ์ํ ๊ด๋ฆฌ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๋จ์ํํ๋ ์ธ๊ธฐ ์๋ ํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. Formik๊ณผ
experimental_useFormStatus๋ฅผ ๊ฒฐํฉํ๋ฉด ํผ์ ์ ์ถ ์ํ๋ฅผ ์ฝ๊ฒ ์ถ์ ํ๊ณ ์ฌ์ฉ์์๊ฒ ์ค์๊ฐ ํผ๋๋ฐฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค. - React Hook Form: React Hook Form์ ๋ฐ์ด๋ ์ฑ๋ฅ๊ณผ ์ ์ฐ์ฑ์ ์ ๊ณตํ๋ ๋ ๋ค๋ฅธ ๋๋ฆฌ ์ฌ์ฉ๋๋ ํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. React Hook Form์
experimental_useFormStatus์ ํตํฉํ๋ฉด ํผ ์ ์ถ์ ๊ด๋ฆฌํ๊ณ ์ํ ์ ๋ฐ์ดํธ๋ฅผ ๊น๋ํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ์์ผ๋ก ํ์ํ ์ ์์ต๋๋ค. - Yup: Yup์ ๊ฐ ํ์ฑ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํ ์คํค๋ง ๋น๋์
๋๋ค. Yup์ ์ฌ์ฉํ์ฌ ํผ์ ์ ํจ์ฑ ๊ฒ์ฌ ์คํค๋ง๋ฅผ ์ ์ํ ์ ์์ผ๋ฉฐ,
experimental_useFormStatus๋ฅผ ์ฌ์ฉํ์ฌ ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ๋ฅผ ์ฌ์ฉ์์๊ฒ ์ค์๊ฐ์ผ๋ก ํ์ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํตํฉํ๋ ค๋ฉด, ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํผ ์ปดํฌ๋ํธ๋ ํธ๋ค๋ฌ ํจ์์ `action` prop์ ์ ๋ฌํ ๋ค์, ์ ์ถ ์ํ๋ฅผ ํ์ํด์ผ ํ๋ ๊ด๋ จ ์ปดํฌ๋ํธ ๋ด์์ `experimental_useFormStatus`๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๋์์ ์ ๊ทผ ๋ฐฉ์๊ณผ์ ๋น๊ต
experimental_useFormStatus ์ด์ ์๋ ๊ฐ๋ฐ์๋ค์ด ํผ ์ ์ถ ์ํ๋ฅผ ์ถ์ ํ๊ธฐ ์ํด ์๋ ์ํ ๊ด๋ฆฌ๋ ์ปค์คํ
ํ
์ ์์กดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์ต๋๋ค. ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ๋ฒ๊ฑฐ๋กญ๊ณ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ์ต๋๋ค. experimental_useFormStatus๋ ํผ ์ ์ถ์ ๊ด๋ฆฌํ๋ ๋ ์ ์ธ์ ์ด๊ณ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ฌ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ์ค์ด๊ณ ์ฝ๋ ๊ฐ๋
์ฑ์ ํฅ์์ํต๋๋ค.
๋ค๋ฅธ ๋์์ผ๋ก๋ ์๋ฌต์ ์ผ๋ก ํผ ์ ์ถ์ ์ฒ๋ฆฌํ ์ ์๋ `react-query`๋ `swr`๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ ์ธก ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์์ ์ ์์ต๋๋ค. ํ์ง๋ง experimental_useFormStatus๋ ํนํ React ์๋ฒ ์ก์
์ ์ฌ์ฉํ ๋ ํผ ์ํ๋ฅผ ์ถ์ ํ๋ ๋ ์ง์ ์ ์ด๊ณ React ์ค์ฌ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
ํ๊ณ ๋ฐ ๊ณ ๋ ค์ฌํญ
experimental_useFormStatus๋ ์๋นํ ์ด์ ์ ์ ๊ณตํ์ง๋ง, ๊ทธ ํ๊ณ์ ๊ณ ๋ ค์ฌํญ์ ์ธ์งํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ์คํ์ ์ํ: ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด,
experimental_useFormStatus๋ ์์ง ์คํ ๋จ๊ณ์ ์์ต๋๋ค. ์ด๋ ํฅํ API๊ฐ ๋ณ๊ฒฝ๋ ์ ์์์ ์๋ฏธํฉ๋๋ค. - ์๋ฒ ์ก์ ์์กด์ฑ: ์ด ํ ์ React ์๋ฒ ์ก์ ๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ฒฐ๋์ด ์์ต๋๋ค. ์ ํต์ ์ธ ํด๋ผ์ด์ธํธ ์ธก ํผ ์ ์ถ๊ณผ๋ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ํธํ์ฑ: ๋์ ๋ธ๋ผ์ฐ์ ๊ฐ React ์๋ฒ ์ก์
๋ฐ
experimental_useFormStatus์ ํ์ํ ๊ธฐ๋ฅ์ ์ง์ํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
๊ฒฐ๋ก
experimental_useFormStatus ํ
์ ๊ฒฌ๊ณ ํ๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ํผ์ ๊ตฌ์ถํ๊ธฐ ์ํ React์ ํดํท์ ๊ท์คํ ์ถ๊ฐ ๊ธฐ๋ฅ์
๋๋ค. ํผ ์ ์ถ ์ํ๋ฅผ ์ถ์ ํ๋ ์ ์ธ์ ์ด๊ณ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ์ ๊ณตํจ์ผ๋ก์จ ํผ ์ฒ๋ฆฌ๋ฅผ ๋จ์ํํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ฉฐ ์ ๊ทผ์ฑ์ ํฅ์์ํต๋๋ค. ์์ง ์คํ ๋จ๊ณ์ ์์ง๋ง, experimental_useFormStatus๋ React์์์ ํผ ๊ฐ๋ฐ ๋ฏธ๋์ ๋ํ ํฐ ๊ฐ๋ฅ์ฑ์ ๋ณด์ฌ์ค๋๋ค. React ์ํ๊ณ๊ฐ ๊ณ์ ์งํํจ์ ๋ฐ๋ผ, ์ด๋ฌํ ๋๊ตฌ๋ฅผ ์์ฉํ๋ ๊ฒ์ ํ๋์ ์ด๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๋ฐ ์ค์ํ ๊ฒ์
๋๋ค.
experimental_useFormStatus ๋ฐ ๊ธฐํ ์คํ์ ๊ธฐ๋ฅ์ ๋ํ ์ต์ ์ ๋ณด๋ ํญ์ ๊ณต์ React ๋ฌธ์๋ฅผ ์ฐธ์กฐํ๋ ๊ฒ์ ์์ง ๋ง์ธ์. ์ฆ๊ฑฐ์ด ์ฝ๋ฉ ๋์ธ์!