experimental_useFormState๋ฅผ ์ฌ์ฉํ์ฌ React ํผ์ ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๋ง์คํฐํ์ธ์. ๊ฒฌ๊ณ ํ ํผ ํธ๋ค๋ง์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก, ๊ตฌํ ์ ๋ต, ๊ณ ๊ธ ๊ธฐ์ ์ ์์๋ณด์ธ์.
React experimental_useFormState ์ค๋ฅ ๋ณต๊ตฌ: ์ข ํฉ ๊ฐ์ด๋
ํผ์ ์ฌ์ฉ์ ์
๋ ฅ๊ณผ ๋ฐ์ดํฐ ์ ์ถ์ ์ฉ์ดํ๊ฒ ํ๋ ๋ํํ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ด์์
๋๋ค. ํนํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋ ๊ฒฌ๊ณ ํ ํผ ์ฒ๋ฆฌ๋ ๊ธ์ ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. React์ experimental_useFormState ํ
์ ํผ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ , ์ค์ํ๊ฒ๋ ์ค๋ฅ๋ฅผ ์ํํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋์์๋ experimental_useFormState์ ์ค๋ฅ ๋ณต๊ตฌ์ ๋ํด ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ๋ฉฐ, ํ๋ ฅ ์๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ํผ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ชจ๋ฒ ์ฌ๋ก, ๊ตฌํ ์ ๋ต, ๊ณ ๊ธ ๊ธฐ์ ์ ์ ๊ณตํฉ๋๋ค.
experimental_useFormState๋ ๋ฌด์์ธ๊ฐ?
experimental_useFormState๋ React 19์์ ๋์
๋ React ํ
์
๋๋ค (์ด ๊ธ์ ์์ฑํ๋ ์์ ์์๋ ์์ง ์คํ์ ์ธ ๊ธฐ๋ฅ์
๋๋ค). ์ด๋ ์
๋ ฅ ๊ฐ, ์ ํจ์ฑ ๊ฒ์ฌ ์ํ, ์ ์ถ ๋ก์ง์ ํฌํจํ ํผ ์ํ ๊ด๋ฆฌ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ํํฉ๋๋ค. ์๋์ ์ธ ์ํ ์
๋ฐ์ดํธ์ ์ค๋ฅ ์ถ์ ์ ์์กดํ๋ ๊ธฐ์กด ๋ฐฉ์๊ณผ ๋ฌ๋ฆฌ, experimental_useFormState๋ ํผ ์ํธ์์ฉ์ ์ฒ๋ฆฌํ๋ ์ ์ธ์ ์ด๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ํนํ ์๋ฒ ์ก์
์ ์ฒ๋ฆฌํ๊ณ ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ํผ๋๋ฐฑ ๋ฃจํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
์ฃผ์ ๊ธฐ๋ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ํ ๊ด๋ฆฌ: ๊ฐ ์ ๋ ฅ ํ๋์ ๋ํ ์๋์ ์ธ ์ํ ์ ๋ฐ์ดํธ ํ์ ์์ด ํผ ๋ฐ์ดํฐ๋ฅผ ์ค์์์ ๊ด๋ฆฌํฉ๋๋ค.
- ์ก์ ์ฒ๋ฆฌ: ์ ๋ ฅ ๊ฐ ์ ๋ฐ์ดํธ๋ ์ ํจ์ฑ ๊ฒ์ฌ ํธ๋ฆฌ๊ฑฐ์ ๊ฐ์ด ํผ ์ํ๋ฅผ ์์ ํ๋ ์ก์ ์ ๋์คํจ์นํ๋ ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํฉ๋๋ค.
- ์ค๋ฅ ์ถ์ : ํด๋ผ์ด์ธํธ์ ์๋ฒ ์์ชฝ์์ ํผ ์ ์ถ ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ถ์ ํ๋ ๋ด์ฅ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
- ๋๊ด์ ์ ๋ฐ์ดํธ: ํผ์ด ์ฒ๋ฆฌ๋๋ ๋์ ์ฌ์ฉ์์๊ฒ ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํ ์ ์๋๋ก ๋๊ด์ ์ ๋ฐ์ดํธ๋ฅผ ์ง์ํฉ๋๋ค.
- ์งํ ํ์๊ธฐ: ์ฌ์ฉ์์๊ฒ ํผ ์ ์ถ ์ํ๋ฅผ ์๋ฆฌ๊ธฐ ์ํ ์งํ ํ์๊ธฐ๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
์ค๋ฅ ๋ณต๊ตฌ๊ฐ ์ค์ํ ์ด์
ํจ๊ณผ์ ์ธ ์ค๋ฅ ๋ณต๊ตฌ๋ ๊ธ์ ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํด ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์ค๋ฅ๋ฅผ ๋ง์ฃผํ์ ๋, ์ ์ค๊ณ๋ ํผ์ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ๋ฉฐ ์คํ ๊ฐ๋ฅํ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์ข์ ๊ฐ์ ๋ฐฉ์งํ๊ณ , ์ดํ๋ฅ ์ ์ค์ด๋ฉฐ, ์ ๋ขฐ๋ฅผ ๊ตฌ์ถํฉ๋๋ค. ์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ๋ถ์กฑํ๋ฉด ํผ๋, ๋ฐ์ดํฐ ์์ค, ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ๋ถ์ ์ ์ธ ์ธ์์ ์ด๋ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ๋ณธ์ ์ฌ์ฉ์๊ฐ ์๋ชป๋ ์ฐํธ๋ฒํธ ํ์์ผ๋ก ํผ์ ์ ์ถํ๋ ค๊ณ ํ ๋, ๋ช ํํ ์๋ด๊ฐ ์๋ค๋ฉด ์ค๋ฅ๋ฅผ ์์ ํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ ์ ์์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก, ๋ ์ผ์ ์ฌ์ฉ์๋ ํ์ง ํ์ค๊ณผ ์ผ์นํ์ง ์๋ ์ ์ฉ์นด๋ ๋ฒํธ ํ์์ ํผ๋์ ๋๋ ์ ์์ต๋๋ค. ์ข์ ์ค๋ฅ ๋ณต๊ตฌ๋ ์ด๋ฌํ ๋ฏธ๋ฌํ ์ฐจ์ด๋ฅผ ํด๊ฒฐํฉ๋๋ค.
๊ฒฌ๊ณ ํ ์ค๋ฅ ๋ณต๊ตฌ๊ฐ ๋ฌ์ฑํ๋ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ : ๋ช ํํ๊ณ ์ ์ตํ ์ค๋ฅ ๋ฉ์์ง๋ ์ฌ์ฉ์๊ฐ ๋ฌธ์ ๋ฅผ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๋๋ก ์๋ดํฉ๋๋ค.
- ํผ ์ดํ ๊ฐ์: ์ ์ฉํ ํผ๋๋ฐฑ์ ์ ๊ณตํจ์ผ๋ก์จ ์ข์ ๊ฐ์ ์ต์ํํ๊ณ ์ฌ์ฉ์๊ฐ ํผ์ ํฌ๊ธฐํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ: ์ ํจํ์ง ์์ ๋ฐ์ดํฐ ์ ์ถ์ ๋ฐฉ์งํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ๋ฐ์ดํฐ์ ์ ํ์ฑ๊ณผ ์ ๋ขฐ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
- ์ ๊ทผ์ฑ ํฅ์: ์ค๋ฅ ๋ฉ์์ง๋ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ฅผ ํฌํจํ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ช ํํ ์๊ฐ์ ์ ํธ์ ์ ์ ํ ARIA ์์ฑ์ ์ ๊ณตํ๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค.
experimental_useFormState๋ฅผ ์ฌ์ฉํ ๊ธฐ๋ณธ ์ค๋ฅ ์ฒ๋ฆฌ
experimental_useFormState๋ฅผ ์ค๋ฅ ์ฒ๋ฆฌ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํ๊ธฐ ์ํด ๊ธฐ๋ณธ์ ์ธ ์์ ๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค. ์ด๋ฉ์ผ์ ์ํ ๋จ์ผ ์
๋ ฅ ํ๋๊ฐ ์๋ ๊ฐ๋จํ ํผ์ ๋ง๋ค๊ณ , ์ด๋ฉ์ผ ์ฃผ์์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๊ณ ์ ํจํ์ง ์์ ๊ฒฝ์ฐ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ๋ฐฉ๋ฒ์ ์์ฐํฉ๋๋ค.
์์ : ์ด๋ฉ์ผ ์ ํจ์ฑ ๊ฒ์ฌ
๋จผ์ ์ด๋ฉ์ผ์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ ์๋ฒ ์ก์ ์ ์ ์ํด ๋ณด๊ฒ ์ต๋๋ค:
```javascript // ์๋ฒ ์ก์ async function validateEmail(prevState, formData) { 'use server'; const email = formData.get('email'); if (!email) { return { error: '์ด๋ฉ์ผ์ ํ์์ ๋๋ค' }; } if (!/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g.test(email)) { return { error: '์ ํจํ์ง ์์ ์ด๋ฉ์ผ ํ์์ ๋๋ค' }; } return { success: true, message: '์ด๋ฉ์ผ์ด ์ ํจํฉ๋๋ค!' }; } ```์ด์ ์ด ์ก์
์ experimental_useFormState๋ฅผ ์ฌ์ฉํ์ฌ React ์ปดํฌ๋ํธ์ ํตํฉํด ๋ณด๊ฒ ์ต๋๋ค:
์ค๋ช :
react-dom์์experimental_useFormState์experimental_useFormStatus๋ฅผ ๊ฐ์ ธ์ต๋๋ค.validateEmail์ก์ ๊ณผ ์ด๊ธฐ ์ํ ๊ฐ์ฒด{ error: null, success: false }๋กuseFormState๋ฅผ ์ด๊ธฐํํฉ๋๋ค.useFormState๊ฐ ๋ฐํํformAction์form์์์actionprop์ผ๋ก ์ ๋ฌํฉ๋๋ค.state๊ฐ์ฒด์์error์์ฑ์ ์ ๊ทผํ๊ณ , ์ค๋ฅ๊ฐ ์กด์ฌํ๋ฉด ๋นจ๊ฐ์ ๋จ๋ฝ์ผ๋ก ํ์ํฉ๋๋ค.useFormStatus๋ฅผ ์ฌ์ฉํ์ฌ ํผ์ด ์ ์ถ๋๋ ๋์ ์ ์ถ ๋ฒํผ์ ๋นํ์ฑํํฉ๋๋ค.
ํด๋ผ์ด์ธํธ ์ธก vs. ์๋ฒ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ
์ ์์ ์์๋ ์๋ฒ์์ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์ด๋ฃจ์ด์ง๋๋ค. ํ์ง๋ง ๋ ๋ฐ์์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํด ํด๋ผ์ด์ธํธ ์ธก์์๋ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ๋ ์๋ฒ ์๋ณต ์์ด ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ํด๋ผ์ด์ธํธ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ๋ ์ฐํ๋ ์ ์์ผ๋ฏ๋ก, ๋ฐฑ์ ์ผ๋ก ์๋ฒ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
ํด๋ผ์ด์ธํธ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ ์์
๋ค์์ ์ด๋ฉ์ผ ํผ์ ํด๋ผ์ด์ธํธ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค:
```javascript 'use client'; import { experimental_useFormStatus as useFormStatus, experimental_useFormState as useFormState } from 'react-dom'; import { useState } from 'react'; function MyForm() { const [state, formAction] = useFormState(validateEmail, { error: null, success: false }); const { pending } = useFormStatus(); const [clientError, setClientError] = useState(null); const handleSubmit = async (event) => { event.preventDefault(); const formData = new FormData(event.target); const email = formData.get('email'); if (!email) { setClientError('์ด๋ฉ์ผ์ ํ์์ ๋๋ค'); return; } if (!/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g.test(email)) { setClientError('์ ํจํ์ง ์์ ์ด๋ฉ์ผ ํ์์ ๋๋ค'); return; } setClientError(null); formAction(formData); }; return ( ); } export default MyForm; ```๋ณ๊ฒฝ ์ฌํญ:
- ํด๋ผ์ด์ธํธ ์ธก ์ค๋ฅ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด
useStateํ ์ ์ถ๊ฐํ์ต๋๋ค. formAction์ ํธ์ถํ๊ธฐ ์ ์ ํด๋ผ์ด์ธํธ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๋handleSubmitํจ์๋ฅผ ๋ง๋ค์์ต๋๋ค.- ํผ์
onSubmitprop์ ์ ๋ฐ์ดํธํ์ฌhandleSubmit์ ํธ์ถํ๋๋ก ํ์ต๋๋ค. - ํด๋ผ์ด์ธํธ ์ธก ์ค๋ฅ๊ฐ ์๋ ๊ฒฝ์ฐ ์ ์ถ ๋ฒํผ์ ๋นํ์ฑํํฉ๋๋ค.
๋ค์ํ ์ค๋ฅ ์ ํ ์ฒ๋ฆฌํ๊ธฐ
ํผ์์๋ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์ค๋ฅ ์ ํ์ด ๋ฐ์ํ ์ ์์ต๋๋ค:
- ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ: ์๋ชป๋ ์ด๋ฉ์ผ ํ์์ด๋ ํ์ ํ๋ ๋๋ฝ๊ณผ ๊ฐ์ ์๋ชป๋ ์ ๋ ฅ ๊ฐ.
- ๋คํธ์ํฌ ์ค๋ฅ: ํผ ์ ์ถ์ ๋ฐฉํดํ๋ ๋คํธ์ํฌ ์ฐ๊ฒฐ ๋ฌธ์ .
- ์๋ฒ ์ค๋ฅ: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๋ฅ๋ ์ธ์ฆ ์คํจ์ ๊ฐ์ด ์ฒ๋ฆฌ ์ค ์๋ฒ ์ธก์์ ๋ฐ์ํ๋ ์ค๋ฅ.
- ๋น์ฆ๋์ค ๋ก์ง ์ค๋ฅ: ์๊ธ ๋ถ์กฑ์ด๋ ์ ํจํ์ง ์์ ํ๋ก๋ชจ์ ์ฝ๋์ ๊ฐ์ด ํน์ ๋น์ฆ๋์ค ๊ท์น๊ณผ ๊ด๋ จ๋ ์ค๋ฅ.
๊ฐ ์ค๋ฅ ์ ํ์ ์ ์ ํ๊ฒ ์ฒ๋ฆฌํ๊ณ , ๊ตฌ์ฒด์ ์ด๊ณ ์ ์ฉํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์์ : ์๋ฒ ์ค๋ฅ ์ฒ๋ฆฌ
validateEmail ์๋ฒ ์ก์
์ ์์ ํ์ฌ ์๋ฒ ์ค๋ฅ๋ฅผ ์๋ฎฌ๋ ์ด์
ํด ๋ณด๊ฒ ์ต๋๋ค:
์ด์ ์ฌ์ฉ์๊ฐ servererror@example.com์ ์
๋ ฅํ๋ฉด ํผ์ ์๋ฒ ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
๊ณ ๊ธ ์ค๋ฅ ๋ณต๊ตฌ ๊ธฐ์
๊ธฐ๋ณธ์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ ์ธ์๋ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํค๊ณ ํผ์ ๋ณต์๋ ฅ์ ๋์ผ ์ ์๋ ๋ช ๊ฐ์ง ๊ณ ๊ธ ๊ธฐ์ ์ด ์์ต๋๋ค.
1. ์ค๋ฅ ๊ฒฝ๊ณ (Error Boundary)
์ค๋ฅ ๊ฒฝ๊ณ๋ ์์ ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ด๋์์๋ JavaScript ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ , ํด๋น ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๋ฉฐ, ์ถฉ๋ํ ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋์ ๋์ฒด UI๋ฅผ ํ์ํ๋ React ์ปดํฌ๋ํธ์ ๋๋ค. ์ค๋ฅ๋ก ์ธํด ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ถฉ๋ํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
```javascript class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // ๋ค์ ๋ ๋๋ง์์ ํด๋ฐฑ UI๋ฅผ ํ์ํ๋๋ก ์ํ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค. return { hasError: true }; } componentDidCatch(error, errorInfo) { // ์ค๋ฅ ๋ณด๊ณ ์๋น์ค์ ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ ์๋ ์์ต๋๋ค. console.error(error, errorInfo); } render() { if (this.state.hasError) { // ์ํ๋ ์ปค์คํ ํด๋ฐฑ UI๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค. return๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
; } return this.props.children; } } export default ErrorBoundary; ```ํผ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ฅ ๊ฒฝ๊ณ๋ก ๊ฐ์ธ ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ ์ ์์ต๋๋ค:
```javascript import ErrorBoundary from './ErrorBoundary'; function App() { return (2. ๋๋ฐ์ด์ฑ(Debouncing)๊ณผ ์ค๋กํ๋ง(Throttling)
๋๋ฐ์ด์ฑ๊ณผ ์ค๋กํ๋ง์ ํจ์๊ฐ ์คํ๋๋ ๋น๋๋ฅผ ์ ํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ธฐ์ ์ ๋๋ค. ์ฌ์ฉ์๊ฐ ํผ์ ์ ๋ ฅํ๋ ๋์ ๊ณผ๋ํ ์ ํจ์ฑ ๊ฒ์ฌ ํธ์ถ์ด๋ API ์์ฒญ์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
๋๋ฐ์ด์ฑ
๋๋ฐ์ด์ฑ์ ํจ์๊ฐ ๋ง์ง๋ง์ผ๋ก ํธ์ถ๋ ํ ์ผ์ ์๊ฐ์ด ์ง๋์ผ๋ง ์คํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ๋ ๋์ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ๋๋ฌด ์์ฃผ ์คํ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
```javascript function debounce(func, delay) { let timeout; return function(...args) { const context = this; clearTimeout(timeout); timeout = setTimeout(() => func.apply(context, args), delay); }; } // ์ฌ์ฉ ์์: const debouncedValidate = debounce(validateEmail, 300); ```์ค๋กํ๋ง
์ค๋กํ๋ง์ ํจ์๊ฐ ํน์ ์๊ฐ ๋์ ์ต๋ ํ ๋ฒ๋ง ์คํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. API ์์ฒญ์ด ๋๋ฌด ์์ฃผ ์ ์ก๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
```javascript function throttle(func, limit) { let inThrottle; return function(...args) { const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => (inThrottle = false), limit); } }; } // ์ฌ์ฉ ์์: const throttledSubmit = throttle(formAction, 1000); ```3. ๋๊ด์ ์ ๋ฐ์ดํธ (Optimistic Updates)
๋๊ด์ ์ ๋ฐ์ดํธ๋ ์๋ฒ๊ฐ ์๋ตํ๊ธฐ ์ ์๋ ํผ ์ ์ถ์ด ์ฑ๊ณตํ ๊ฒ์ฒ๋ผ UI๋ฅผ ์ ๋ฐ์ดํธํ์ฌ ์ฌ์ฉ์์๊ฒ ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด๊ฐ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์๋ฒ๊ฐ ์ค๋ฅ๋ฅผ ๋ฐํํ๋ฉด UI๋ ์ค๋ฅ๋ฅผ ๋ฐ์ํ๋๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
experimental_useFormState๋ ์๋ฒ ์ก์
์ด ์คํจํ๊ณ ์ค๋ฅ๋ฅผ ๋ฐํํ ๊ฒฝ์ฐ ๋๋๋ฆฌ๋ ๋ฐฉ์์ผ๋ก ๋๊ด์ ์
๋ฐ์ดํธ๋ฅผ ์๋ฌต์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
4. ์ ๊ทผ์ฑ ๊ณ ๋ ค ์ฌํญ
์ค๋ฅ ๋ฉ์์ง๊ฐ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ฅผ ํฌํจํ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ํด์ผ ํฉ๋๋ค. ์๋งจํฑ HTML ์์๋ฅผ ์ฌ์ฉํ๊ณ , ๋ช ํํ ์๊ฐ์ ์ ํธ๋ฅผ ์ ๊ณตํ๋ฉฐ, ARIA ์์ฑ์ ์ฌ์ฉํ์ฌ ์ ๊ทผ์ฑ์ ํฅ์์ํค์ธ์.
- ์๋งจํฑ HTML ์ฌ์ฉ:
<label>๊ณผ<input>๊ณผ ๊ฐ์ ์ ์ ํ HTML ์์๋ฅผ ์ฌ์ฉํ์ฌ ํผ์ ๊ตฌ์กฐํํ์ธ์. - ๋ช ํํ ์๊ฐ์ ์ ํธ ์ ๊ณต: ์์, ์์ด์ฝ, ์ค๋ช ์ ์ธ ํ ์คํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ๋ฅผ ๊ฐ์กฐํ์ธ์. ์ ์๋ ฅ ์ฌ์ฉ์๋ฅผ ์ํด ์์ ๋๋น๊ฐ ์ถฉ๋ถํ์ง ํ์ธํ์ธ์.
- ARIA ์์ฑ ์ฌ์ฉ:
aria-invalid์aria-describedby์ ๊ฐ์ ARIA ์์ฑ์ ์ฌ์ฉํ์ฌ ๋ณด์กฐ ๊ธฐ์ ์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ธ์. - ํค๋ณด๋ ํ์: ์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ฅผ ์ฌ์ฉํ์ฌ ํผ์ ํ์ํ๊ณ ์ค๋ฅ ๋ฉ์์ง์ ์ ๊ทผํ ์ ์๋๋ก ํ์ธ์.
5. ํ์งํ ๋ฐ ๊ตญ์ ํ
์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํผ์ ๊ฐ๋ฐํ ๋๋ ํ์งํ์ ๊ตญ์ ํ๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ ํผ์ ๋ค๋ฅธ ์ธ์ด, ๋ฌธํ, ์ง์ญ ํ์ค์ ๋ง๊ฒ ์กฐ์ ํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
- ํ์งํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ:
i18next๋react-intl๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒ์ญ์ ๊ด๋ฆฌํ์ธ์. - ๋ ์ง ๋ฐ ์ซ์ ์์ ์ง์ : ์ฌ์ฉ์์ ๋ก์ผ์ผ์ ๋ฐ๋ผ ๋ ์ง, ์ซ์, ํตํ์ ์ ์ ํ ์์์ ์ฌ์ฉํ์ธ์.
- ๋ค์ํ ์ ๋ ฅ ํ์ ์ฒ๋ฆฌ: ๊ตญ๊ฐ๋ณ๋ก ์ ํ๋ฒํธ, ์ฐํธ๋ฒํธ, ์ฃผ์ ๋ฑ ๋ค๋ฅธ ์ ๋ ฅ ํ์์ ์ธ์งํ๊ณ ์์ด์ผ ํฉ๋๋ค.
- ์ฌ๋ฌ ์ธ์ด๋ก ๋ช ํํ ์ง์นจ ์ ๊ณต: ํผ ์ง์นจ๊ณผ ์ค๋ฅ ๋ฉ์์ง๊ฐ ์ฌ๋ฌ ์ธ์ด๋ก ์ ๊ณต๋๋๋ก ํ์ธ์.
์๋ฅผ ๋ค์ด, ์ ํ๋ฒํธ ํ๋๋ ์ฌ์ฉ์์ ์์น์ ๋ฐ๋ผ ๋ค๋ฅธ ํ์์ ์์ฉํด์ผ ํ๋ฉฐ, ์ค๋ฅ ๋ฉ์์ง๋ ํด๋น ์ธ์ด๋ก ํ์งํ๋์ด์ผ ํฉ๋๋ค.
experimental_useFormState๋ฅผ ์ฌ์ฉํ ์ค๋ฅ ๋ณต๊ตฌ ๋ชจ๋ฒ ์ฌ๋ก
experimental_useFormState๋ก ์ค๋ฅ ๋ณต๊ตฌ๋ฅผ ๊ตฌํํ ๋ ๋ช
์ฌํด์ผ ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ์ค๋ฅ ๋ฉ์์ง ์ ๊ณต: ์ค๋ฅ ๋ฉ์์ง๋ ์ดํดํ๊ธฐ ์ฝ๊ณ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์ง์นจ์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
- ์ ์ ํ ์ค๋ฅ ์์ค ์ฌ์ฉ: ๋ฌธ์ ์ ์ฌ๊ฐ๋๋ฅผ ๋ํ๋ด๊ธฐ ์ํด ๋ค์ํ ์ค๋ฅ ์์ค(์: ๊ฒฝ๊ณ , ์ค๋ฅ)์ ์ฌ์ฉํ์ธ์.
- ์ค๋ฅ๋ฅผ ์ํํ๊ฒ ์ฒ๋ฆฌ: ์ค๋ฅ๋ก ์ธํด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ค๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ ๋์ฒด UI๋ฅผ ์ ๊ณตํ์ธ์.
- ๋๋ฒ๊น ์ ์ํด ์ค๋ฅ ๊ธฐ๋ก: ๋๋ฒ๊น ๋ฐ ๋ฌธ์ ํด๊ฒฐ์ ์ฉ์ดํ๊ฒ ํ๊ธฐ ์ํด ์ค๋ฅ๋ฅผ ์ค์ ์์น์ ๊ธฐ๋กํ์ธ์.
- ์ค๋ฅ ์ฒ๋ฆฌ ํ ์คํธ: ์ค๋ฅ ์ฒ๋ฆฌ ๋ก์ง์ด ์์๋๋ก ์๋ํ๋์ง ์ฒ ์ ํ ํ ์คํธํ์ธ์.
- ์ฌ์ฉ์ ๊ฒฝํ ๊ณ ๋ ค: ์ฌ์ฉ์๋ฅผ ์ผ๋์ ๋๊ณ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ค๊ณํ์ฌ ์ํํ๊ณ ์ง๊ด์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ์ธ์.
๊ฒฐ๋ก
experimental_useFormState๋ React ์ ํ๋ฆฌ์ผ์ด์
์์ ํผ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋์์ ์ค๋ช
ํ ๋ชจ๋ฒ ์ฌ๋ก์ ๊ธฐ์ ์ ๋ฐ๋ฅด๋ฉด, ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋์๋ ์ฌ์ฉ์์๊ฒ ๊ธ์ ์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ๋ ๊ฒฌ๊ณ ํ๊ณ ์ฌ์ฉ์ ์นํ์ ์ธ ํผ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๋ช
ํํ ์ค๋ฅ ๋ฉ์์ง, ์ ๊ทผ์ฑ ์๋ ๋์์ธ, ์ฒ ์ ํ ํ
์คํธ๋ฅผ ์ฐ์ ์ํ์ฌ ํผ์ด ํ๋ ฅ ์๊ณ ์ ๋ขฐํ ์ ์๋๋ก ํ์ธ์.
experimental_useFormState๊ฐ ์ฑ์ํด์ง๊ณ React์ ์์ ์ ์ธ ์ผ๋ถ๊ฐ ๋จ์ ๋ฐ๋ผ, ๊ทธ ๊ธฐ๋ฅ์ ๋ง์คํฐํ๋ ๊ฒ์ ๊ณ ํ์ง์ ๋ํํ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๋ฐ ํ์์ ์ด ๋ ๊ฒ์
๋๋ค. ๊ทธ ์ ์ฌ๋ ฅ์ ์ต๋ํ ๋ฐํํ๊ณ ๋ฐ์ด๋ ํผ ๊ฒฝํ์ ๋ง๋ค๊ธฐ ์ํด ๊ณ์ํด์ ์คํํ๊ณ ๊ธฐ๋ฅ์ ํ์ํ์ธ์.