React์ useFormStatus ํ ์ ํ์ฉํ ๊ฐ์ํ๋ ํผ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์: ์ ์ถ ์ํ, ์ค๋ฅ ์ฒ๋ฆฌ, ํฅ์๋ ์ฌ์ฉ์ ๊ฒฝํ. ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก ํฌํจ.
React useFormStatus: ํผ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ์ข ํฉ ๊ฐ์ด๋
React 18์ ๋์
๋ useFormStatus ํ
์ React ์๋ฒ ์ปดํฌ๋ํธ ๋ด์์ ํผ์ ์ ์ถ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด ํ
์ ์๋ฒ ์ก์
๊ณผ ํจ๊ป ์๋ํ๋๋ก ํน๋ณํ ์ค๊ณ๋์ด, ์๋ฒ์์ ์ง์ ํผ ์ ์ถ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ํํ ํตํฉ์ ์ ๊ณตํฉ๋๋ค. ํผ ์ ์ถ ์ํ๋ฅผ ์ถ์ ํ๋ ๊ณผ์ ์ ๋จ์ํํ์ฌ, ํผ์ด ๋ณด๋ฅ ์ค์ธ์ง, ์ฑ๊ณตํ๋์ง, ๋๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง์ ๊ฐ์ ๊ฐ์น ์๋ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋์์๋ useFormStatus์ ๊ธฐ๋ฅ, ์ด์ ๋ฐ ๋ค์ํ ์๋๋ฆฌ์ค์์ ์ฌ์ฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ์ค์ ์์ ๋ฅผ ์ดํด๋ด
๋๋ค.
์๋ฒ ์ก์ ๊ณผ useFormStatus ์ดํดํ๊ธฐ
useFormStatus์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ ์ ์ React ์๋ฒ ์ปดํฌ๋ํธ์ ์๋ฒ ์ก์
์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์๋ฒ ์ก์
์ ์ฌ์ฉํ๋ฉด ์๋ฒ์์ ์คํ๋๋ ํจ์๋ฅผ ์ ์ํ๊ณ React ์ปดํฌ๋ํธ์์ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ณ๋์ API ์๋ํฌ์ธํธ ์์ด ํผ ์ ์ถ, ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฐ ๊ธฐํ ์๋ฒ ์ธก ์์
์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
useFormStatus ํ
์ ํผ ์ ์ถ์ ์ํด ํธ๋ฆฌ๊ฑฐ๋ ์ด๋ฌํ ์๋ฒ ์ก์
์ ์คํ์ ๋ํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค.
useFormStatus๋ ๋ฌด์์ธ๊ฐ?
useFormStatus๋ ๊ฐ์ฅ ์ต๊ทผ์ ํผ ์ ์ถ ์ํ์ ๋ํ ์ ๋ณด๋ฅผ ๋ด์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ React ํ
์
๋๋ค. ์ด ์ ๋ณด์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
- pending: ํผ์ด ํ์ฌ ์ ์ถ ์ค์ธ์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ ๊ฐ์ ๋๋ค.
- data: ์ ์ถ๊ณผ ๊ด๋ จ๋
FormData๊ฐ์ฒด์ ๋๋ค. - method: ์ ์ถ์ ์ฌ์ฉ๋ HTTP ๋ฉ์๋์ ๋๋ค (์ผ๋ฐ์ ์ผ๋ก 'POST').
- action: ํธ๋ฆฌ๊ฑฐ๋ ์๋ฒ ์ก์ ํจ์์ ๋๋ค.
useFormStatus ์ฌ์ฉ์ ์ด์
useFormStatus๋ฅผ ํ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ฃผ์ ์ด์ ์ด ์์ต๋๋ค:
- ๋จ์ํ๋ ์ํ ๊ด๋ฆฌ: ํผ ์ ์ถ ์ํ๋ฅผ ์ถ์ ํ๊ธฐ ์ํ ์๋ ์ํ ๊ด๋ฆฌ๊ฐ ํ์ ์์ด์ง๋๋ค. ํ ์ ์ ์ถ์ด ์งํ๋จ์ ๋ฐ๋ผ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
- ํฅ์๋ ์ฌ์ฉ์ ๊ฒฝํ: ํผ์ด ์ฒ๋ฆฌ๋๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ฑฐ๋ ์คํจ ์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ฑ ์ฌ์ฉ์์๊ฒ ์ค์๊ฐ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค.
- ๊นจ๋ํ ์ฝ๋: ํผ ์ ์ถ ๋ก์ง์ ์ปดํฌ๋ํธ ๋ ๋๋ง๊ณผ ๋ถ๋ฆฌํ์ฌ ๋ ์ ์ธ์ ์ด๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์ด์งํฉ๋๋ค.
- ์๋ฒ ์ก์ ๊ณผ์ ์ํํ ํตํฉ: ์๋ฒ ์ก์ ๊ณผ ์๋ฒฝํ๊ฒ ์๋ํ๋๋ก ์ค๊ณ๋์ด ์๋ฒ์์ ์ง์ ํผ ์ ์ถ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
useFormStatus์ ์ค์ ์์
๋ค์ํ ์๋๋ฆฌ์ค์์ useFormStatus์ ์ฌ์ฉ๋ฒ์ ์ค๋ช
ํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ค์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋ก๋ฉ ํ์๊ธฐ๊ฐ ์๋ ๊ธฐ๋ณธ ํผ ์ ์ถ
์ด ์์ ๋ ํผ์ด ์ ์ถ๋๋ ๋์ ํ์๋๋ ๋ก๋ฉ ํ์๊ธฐ๊ฐ ์๋ ๊ฐ๋จํ ํผ์ ๋ณด์ฌ์ค๋๋ค.
์๋ฒ ์ก์ (actions.js):
'use server'
export async function submitForm(formData) {
// ๋ก๋ฉ ์ํ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ์ง์ฐ์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
await new Promise(resolve => setTimeout(resolve, 2000));
const name = formData.get('name');
console.log('Form submitted with name:', name);
return { message: `Form submitted successfully with name: ${name}` };
}
React ์ปดํฌ๋ํธ (FormComponent.jsx):
'use client'
import { useFormStatus } from 'react-dom'
import { submitForm } from './actions'
function FormComponent() {
const { pending } = useFormStatus()
return (
)
}
export default FormComponent
์ด ์์ ์์๋ useFormStatus์ pending ์์ฑ์ ์ฌ์ฉํ์ฌ ํผ์ด ์ ์ถ๋๋ ๋์ ์
๋ ฅ ํ๋์ ๋ฒํผ์ ๋นํ์ฑํํ๊ณ "์ ์ถ ์ค..." ๋ฉ์์ง๋ฅผ ํ์ํฉ๋๋ค.
์ฑ๊ณต ๋ฐ ์ค๋ฅ ์ํ ์ฒ๋ฆฌ
์ด ์์ ๋ ํผ ์ ์ถ ํ ์ฑ๊ณต ๋ฐ ์ค๋ฅ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
์๋ฒ ์ก์ (actions.js):
'use server'
export async function submitForm(formData) {
// ์ง์ฐ์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
await new Promise(resolve => setTimeout(resolve, 2000));
const name = formData.get('name');
if (!name) {
throw new Error('์ด๋ฆ์ ํ์ ํญ๋ชฉ์
๋๋ค');
}
console.log('Form submitted with name:', name);
return { message: `Form submitted successfully with name: ${name}` };
}
React ์ปดํฌ๋ํธ (FormComponent.jsx):
'use client'
import { useFormStatus } from 'react-dom'
import { submitForm } from './actions'
import { useState } from 'react'
function FormComponent() {
const { pending } = useFormStatus()
const [message, setMessage] = useState(null);
const [error, setError] = useState(null);
async function handleSubmit(formData) {
try {
const result = await submitForm(formData);
setMessage(result.message);
setError(null);
} catch (e) {
setError(e.message);
setMessage(null);
}
}
return (
)
}
export default FormComponent
์ด ์์ ์์๋ handleSubmit ํจ์์์ try/catch ๋ธ๋ก์ ์ฌ์ฉํฉ๋๋ค. ์๋ฒ ์ก์
์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฅผ ํฌ์ฐฉํ์ฌ ์ฌ์ฉ์์๊ฒ ํ์ํฉ๋๋ค. ์ ์ถ์ด ์ฑ๊ณตํ๋ฉด ์ฑ๊ณต ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
๋ณต์กํ ๋ฐ์ดํฐ๋ฅผ ์ํ FormData ์ฌ์ฉ
useFormStatus๋ FormData์ ์ํํ๊ฒ ์๋ํ์ฌ ๋ณต์กํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ค์์ ํ์ผ ์
๋ก๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ์์ ์
๋๋ค.
์๋ฒ ์ก์ (actions.js):
'use server'
export async function uploadFile(formData) {
// ํ์ผ ์ฒ๋ฆฌ๋ฅผ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
await new Promise(resolve => setTimeout(resolve, 2000));
const file = formData.get('file');
if (!file) {
throw new Error('์
๋ก๋๋ ํ์ผ์ด ์์ต๋๋ค');
}
console.log('File uploaded:', file.name);
return { message: `File uploaded successfully: ${file.name}` };
}
React ์ปดํฌ๋ํธ (FormComponent.jsx):
'use client'
import { useFormStatus } from 'react-dom'
import { uploadFile } from './actions'
import { useState } from 'react'
function FormComponent() {
const { pending } = useFormStatus()
const [message, setMessage] = useState(null);
const [error, setError] = useState(null);
async function handleSubmit(formData) {
try {
const result = await uploadFile(formData);
setMessage(result.message);
setError(null);
} catch (e) {
setError(e.message);
setMessage(null);
}
}
return (
)
}
export default FormComponent
์ด ์์ ๋ FormData๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ ์
๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ์๋ฒ ์ก์
์ FormData ๊ฐ์ฒด์์ ํ์ผ์ ๊ฒ์ํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค. useFormStatus ํ
์ ํ์ผ์ด ์
๋ก๋๋๋ ๋์ ๋ก๋ฉ ์ํ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
useFormStatus ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
useFormStatus์ ์ด์ ์ ๊ทน๋ํํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- ๋ช
ํํ ์ฌ์ฉ์ ํผ๋๋ฐฑ ์ ๊ณต:
pending์ํ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ตํ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ณ ์ฌ๋ฌ ๋ฒ์ ์ ์ถ์ ๋ฐฉ์งํ๊ธฐ ์ํด ํผ ์์๋ฅผ ๋นํ์ฑํํ์ญ์์ค. - ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌ: ์๋ฒ ์ก์ ์์ ์์ธ๋ฅผ ํฌ์ฐฉํ๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ธฐ ์ํด ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์ญ์์ค.
- ์๋ฒ์์ ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ: ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ๊ณผ ๋ณด์์ ๋ณด์ฅํ๊ธฐ ์ํด ์๋ฒ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ์ญ์์ค.
- ์๋ฒ ์ก์ ์ ๊ฐ๊ฒฐํ๊ฒ ์ ์ง: ์ฑ๋ฅ๊ณผ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํค๊ธฐ ์ํด ์๋ฒ ์ก์ ์ ํน์ ์์ ์ ์ง์ค์ํค์ญ์์ค.
- ์ ๊ทผ์ฑ ๊ณ ๋ ค: ์ ์ ํ ๋ ์ด๋ธ, ARIA ์์ฑ ๋ฐ ํค๋ณด๋ ํ์ ์ง์์ ์ ๊ณตํ์ฌ ํผ์ ์ ๊ทผํ ์ ์๋๋ก ํ์ญ์์ค.
๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก
๊ธฐ๋ณธ์ ์ธ ์์ ์ธ์๋ useFormStatus๋ ๋ ๋ณต์กํ ์๋๋ฆฌ์ค์์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค:
- ์ ์ง์ ํฅ์: ์๋ฒ ์ก์
๊ณผ
useFormStatus๋ฅผ ์ฌ์ฉํ์ฌ ํผ์ ์ ์ง์ ์ผ๋ก ํฅ์์ํค์ญ์์ค. JavaScript๊ฐ ๋นํ์ฑํ๋ ์ฌ์ฉ์์๊ฒ๋ ๊ธฐ๋ณธ ๊ฒฝํ์ ์ ๊ณตํ๊ณ JavaScript๊ฐ ํ์ฑํ๋ ์ฌ์ฉ์์๊ฒ๋ ๋ ํ๋ถํ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค. - ๋๊ด์ ์ ๋ฐ์ดํธ: ํผ์ด ์ ์ถ๋ ์งํ UI๋ฅผ ์ฆ์ ์ ๋ฐ์ดํธํ์ฌ ๋๊ด์ ์ ๋ฐ์ดํธ๋ฅผ ๊ตฌํํ๊ณ , ์ ์ถ์ด ์ฑ๊ณตํ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ์ ์ถ์ด ์คํจํ๋ฉด ์ ๋ฐ์ดํธ๋ฅผ ๋๋๋ฆฝ๋๋ค.
- ํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํตํฉ:
useFormStatus๋ฅผ Formik์ด๋ React Hook Form๊ณผ ๊ฐ์ ์ธ๊ธฐ ์๋ ํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํตํฉํ์ฌ ํผ ์ํ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์ฒด ์ํ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์์ง๋ง,useFormStatus๋ ์๋ฒ ์ก์ ์ ๋ํ ์ต์ข ์ ์ถ ๋จ๊ณ์์ ์ ์ฉํ ์ ์์ต๋๋ค.
๊ตญ์ ํ(i18n) ๊ณ ๋ ค ์ฌํญ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ํผ์ ๊ตฌ์ถํ ๋ ๊ตญ์ ํ(i18n)๋ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ค์์ useFormStatus๋ฅผ ์ฌ์ฉํ ๋ i18n์ ๊ณ ๋ คํ๋ ๋ฐฉ๋ฒ์
๋๋ค:
- ์ง์ญํ๋ ์ค๋ฅ ๋ฉ์์ง: ์ฌ์ฉ์์๊ฒ ํ์๋๋ ์ค๋ฅ ๋ฉ์์ง๊ฐ ์ ํธํ๋ ์ธ์ด๋ก ์ง์ญํ๋๋๋ก ํ์ญ์์ค. ์ด๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฒ์ญ ํ์ผ์ ์ ์ฅํ๊ณ
react-intl์ด๋i18next์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ ํ ๋ฒ์ญ์ ๊ฒ์ํจ์ผ๋ก์จ ๋ฌ์ฑํ ์ ์์ต๋๋ค. - ๋ ์ง ๋ฐ ์ซ์ ํ์ ์ง์ : ์ฌ์ฉ์์ ๋ก์ผ์ผ์ ๋ฐ๋ผ ๋ ์ง ๋ฐ ์ซ์ ํ์์ ์ฒ๋ฆฌํ์ญ์์ค.
Intl.DateTimeFormat๋ฐIntl.NumberFormat๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ๊ฐ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ํํ์ญ์์ค. - ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ(RTL) ์ง์: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก ์ฐ๋ ์ธ์ด(์: ์๋์ด, ํ๋ธ๋ฆฌ์ด)๋ฅผ ์ง์ํ๋ ๊ฒฝ์ฐ, ํผ์ด RTL ๋ ์ด์์์ ์์ฉํ๋๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์คํ์ผ๋ง๋์๋์ง ํ์ธํ์ญ์์ค.
- ํผ ์ ํจ์ฑ ๊ฒ์ฌ: ๋ค๋ฅธ ๋ก์ผ์ผ์ ๋ง๊ฒ ํผ ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น์ ์กฐ์ ํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ์ ํ๋ฒํธ ์ ํจ์ฑ ๊ฒ์ฌ๋ ๊ตญ๊ฐ๋ง๋ค ํฌ๊ฒ ๋ค๋ฅผ ์ ์์ต๋๋ค.
์ง์ญํ๋ ์ค๋ฅ ๋ฉ์์ง ์์ :
// translations/ko.json
{
"form.error.nameRequired": "์ด๋ฆ์ ์
๋ ฅํด์ฃผ์ธ์.",
"form.success.submission": "์ ์ถํด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค!"
}
// translations/en.json
{
"form.error.nameRequired": "Please enter your name.",
"form.success.submission": "Thank you for your submission!"
}
// react-intl์ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ
import { useIntl } from 'react-intl';
function FormComponent() {
const intl = useIntl();
const [error, setError] = useState(null);
// ...
catch (e) {
setError(intl.formatMessage({ id: 'form.error.nameRequired' }));
}
}
์ ๊ทผ์ฑ ๊ณ ๋ ค ์ฌํญ
์ ๊ทผ์ฑ์ ํฌ๊ด์ ์ธ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๋ฐ ์์ด ํต์ฌ์ ์ธ ์ธก๋ฉด์
๋๋ค. ๋ค์์ useFormStatus๋ฅผ ์ฌ์ฉํ ๋ ์ผ๋์ ๋์ด์ผ ํ ๋ช ๊ฐ์ง ์ ๊ทผ์ฑ ๊ณ ๋ ค ์ฌํญ์
๋๋ค:
- ARIA ์์ฑ: ARIA ์์ฑ์ ์ฌ์ฉํ์ฌ ๋ณด์กฐ ๊ธฐ์ ์ ํผ์ ์ํ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ํผ์ด ๋ณด๋ฅ ์ค์ผ ๋ ์ ์ถ ๋ฒํผ์
aria-busy="true"๋ฅผ ์ฌ์ฉํ์ญ์์ค. - ๋ ์ด๋ธ: ๋ชจ๋ ํผ ํ๋์
<label>์์๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ ฅ ์์์ ์ฐ๊ฒฐ๋ ๋ช ํํ๊ณ ์ค๋ช ์ ์ธ ๋ ์ด๋ธ์ด ์๋์ง ํ์ธํ์ญ์์ค. - ์ค๋ฅ ๋ฉ์์ง: ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๊ฐ ์ฝ๊ฒ ์์๋ณด๊ณ ์ดํดํ ์ ์๋ ๋ฐฉ์์ผ๋ก ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ์ญ์์ค.
aria-live="assertive"์ ๊ฐ์ ARIA ์์ฑ์ ์ฌ์ฉํ์ฌ ์คํฌ๋ฆฐ ๋ฆฌ๋์๊ฒ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์๋ฆฌ์ญ์์ค. - ํค๋ณด๋ ํ์: ์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ง์ผ๋ก ํผ์ ํ์ํ ์ ์๋๋ก ํ์ญ์์ค.
tabindex์์ฑ์ ์ฌ์ฉํ์ฌ ์์๊ฐ ํฌ์ปค์ค๋ฅผ ๋ฐ๋ ์์๋ฅผ ์ ์ดํ์ญ์์ค. - ์์ ๋๋น: ํผ์ ์ฌ์ฉ๋ ํ ์คํธ์ ๋ฐฐ๊ฒฝ์์ด ์๊ฐ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๊ฐ ์ฝ๊ฒ ์ฝ์ ์ ์๋๋ก ์ถฉ๋ถํ ๋๋น๋ฅผ ๊ฐ๋๋ก ํ์ญ์์ค.
useFormStatus ๋ ์ ํต์ ์ธ ์ํ ๊ด๋ฆฌ
์ ํต์ ์ผ๋ก React ๊ฐ๋ฐ์๋ค์ ์ปดํฌ๋ํธ ์ํ(useState)๋ ๋ ๋ณต์กํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: Redux, Zustand)๋ฅผ ์ฌ์ฉํ์ฌ ํผ ์ ์ถ ์ํ๋ฅผ ๊ด๋ฆฌํด์์ต๋๋ค. ๋ค์์ ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์๊ณผ useFormStatus๋ฅผ ๋น๊ตํ ๊ฒ์
๋๋ค:
| ๊ธฐ๋ฅ | useFormStatus | useState | ์ธ๋ถ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ |
|---|---|---|---|
| ๋ณต์ก์ฑ | ๋ฎ์ | ์ค๊ฐ | ๋์ |
| ์๋ฒ ์ก์ ๊ณผ์ ํตํฉ | ์ํํจ | ์๋ ํตํฉ ํ์ | ์๋ ํตํฉ ํ์ |
| ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋ | ์ต์ | ๋ณดํต | ์๋นํจ |
| ์ ํฉํ ์ฌ์ฉ ์ฌ๋ก | ์๋ฒ ์ก์ ์ ์ง์ ์ ์ถํ๋ ํผ | ์ ํ๋ ์ํ๋ฅผ ๊ฐ์ง ๊ฐ๋จํ ํผ | ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ๊ฑธ์ณ ์ํ๋ฅผ ๊ณต์ ํ๋ ๋ณต์กํ ํผ |
useFormStatus๋ ํผ์ด React ์๋ฒ ์ก์
๊ณผ ์ง์ ์ํธ ์์ฉํ ๋ ๋น์ ๋ฐํฉ๋๋ค. ๋ณด์ผ๋ฌํ๋ ์ดํธ๋ฅผ ์ค์ด๊ณ ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ๊ฑธ์ณ ์ํ๋ฅผ ๊ณต์ ํ๋ ๋งค์ฐ ๋ณต์กํ ํผ์ ๊ฒฝ์ฐ, ๋ณธ๊ฒฉ์ ์ธ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ฌ์ ํ ํ์ํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ธ ๋ฌธ์ ํด๊ฒฐ
๋ค์์ useFormStatus๋ฅผ ์ฌ์ฉํ ๋ ๋ฐ์ํ ์ ์๋ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์
๋๋ค:
useFormStatus๊ฐ ์ ๋ฐ์ดํธ๋์ง ์์:action์์ฑ์ด ์๋ฒ ์ก์ ์ผ๋ก ์ค์ ๋<form>์์ ๋ด์์useFormStatus๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํ์ญ์์ค.- ์๋ฒ ์ก์ ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ ์๋๊ณ ๋ด๋ณด๋ด์ก๋์ง ํ์ธํ์ญ์์ค.
- ์๋ฒ ์ก์ ์์ ์ฑ๊ณต์ ์ธ ์๋ฃ๋ฅผ ๋ฐฉํดํ ์ ์๋ ์ค๋ฅ๊ฐ ์๋์ง ํ์ธํ์ญ์์ค.
- ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋์ง ์์:
- ์๋ฒ ์ก์ ์์ ์ค๋ฅ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ํฌ์ฐฉํ๊ณ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฐํํ๊ณ ์๋์ง ํ์ธํ์ญ์์ค.
- ์ปดํฌ๋ํธ์์
error์ํ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๊ณ ์๋์ง ํ์ธํ์ญ์์ค.
- ๋ก๋ฉ ํ์๊ธฐ๊ฐ ๋ํ๋์ง ์์:
useFormStatus์pending์ํ๋ฅผ ์ฌ์ฉํ์ฌ ์กฐ๊ฑด๋ถ๋ก ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ณ ์๋์ง ํ์ธํ์ญ์์ค.- ์๋ฒ ์ก์ ์ด ์ค์ ๋ก ์๋ฃ๋๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋์ง ํ์ธํ์ญ์์ค(์: ์ง์ฐ ์๋ฎฌ๋ ์ด์ ).
๊ฒฐ๋ก
useFormStatus๋ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ React ์ ํ๋ฆฌ์ผ์ด์
์์ ํผ ์ ์ถ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊น๋ํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด ํ
์ ํ์ฉํ๋ฉด ์ฝ๋๋ฅผ ๋จ์ํํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ฉฐ ์๋ฒ ์ก์
๊ณผ ์ํํ๊ฒ ํตํฉํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋์์๋ useFormStatus์ ๊ธฐ๋ณธ ์ฌํญ์ ๋ค๋ฃจ๊ณ , ์ค์ ์์ ๋ฅผ ์ ๊ณตํ๋ฉฐ, ํจ๊ณผ์ ์ธ ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋
ผ์ํ์ต๋๋ค. useFormStatus๋ฅผ React ํ๋ก์ ํธ์ ํตํฉํจ์ผ๋ก์จ ํผ ์ฒ๋ฆฌ๋ฅผ ๊ฐ์ํํ๊ณ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํ ๋ ๊ฐ๋ ฅํ๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.