๐Ÿ“ 9. HTML `form` ํƒœ๊ทธ์™€ React์—์„œ Controlled vs Uncontrolled ํผ ์ œ๋Œ€๋กœ ๊ตฌ๋ถ„ํ•ด๋ดค๋‹ค

JM_Devยท2025๋…„ 4์›” 24์ผ
1
post-thumbnail

HTML์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์—์„œ form ํƒœ๊ทธ๋Š” ๋„ˆ๋ฌด ์ต์ˆ™ํ•˜์ง€๋งŒ,
React๋กœ ํผ์„ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด Controlled์™€ Uncontrolled์˜ ๊ฐœ๋…์ด ์ƒ๊ธฐ๋ฉด์„œ ํ˜ผ๋ž€์ด ์‹œ์ž‘๋œ๋‹ค.
์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๊ธฐ๋ณธ ๊ฐœ๋…๋ถ€ํ„ฐ React์˜ ์ž…๋ ฅ ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐฉ์‹๊นŒ์ง€ ์ „๋ถ€ ์ •๋ฆฌํ•ด๋ดค๋‹ค.


โœ… HTML์—์„œ์˜ ๊ธฐ๋ณธ form

<form action="/submit" method="POST">
  <label>
    ์ด๋ฆ„: <input type="text" name="username" />
  </label>
  <button type="submit">์ œ์ถœ</button>
</form>

์ฃผ์š” ์†์„ฑ

  • action: ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  URL
  • method: ์ „์†ก ๋ฐฉ์‹ (GET, POST, etc.)
  • name: ์„œ๋ฒ„๋กœ ์ „์†ก๋  key
  • onSubmit: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅ

โœ… React์—์„œ์˜ Form์€ ์ƒํƒœ๊ด€๋ฆฌ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‚˜๋‰œ๋‹ค

React์—์„œ๋Š” ๋ณดํ†ต onChange๋กœ ๊ฐ’์„ ๋ฐ›์•„ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ,
์ด๋•Œ ์ƒํƒœ์™€ input์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ 2๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค.


๐Ÿ”น Controlled Form

์ƒํƒœ(useState)๋กœ ์ž…๋ ฅ๊ฐ’์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, value์™€ onChange๊ฐ€ ๋ฐ”์ธ๋”ฉ๋จ

const [name, setName] = useState('');

return (
  <form onSubmit={handleSubmit}>
    <input
      type="text"
      value={name}
      onChange={(e) => setName(e.target.value)}
    />
    <button type="submit">์ œ์ถœ</button>
  </form>
);

์žฅ์ 

  • React์—์„œ ๋ชจ๋“  ์ƒํƒœ๋ฅผ ์ถ”์  ๊ฐ€๋Šฅ
  • ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(validation)๊ณผ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์ด ์‰ฌ์›€

๋‹จ์ 

  • ์ž…๋ ฅ๊ฐ’๋งˆ๋‹ค ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜๋ฏ€๋กœ ๋งŽ์•„์ง€๋ฉด ์„ฑ๋Šฅ์— ์˜ํ–ฅ
  • boilerplate ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง

๐Ÿ”น Uncontrolled Form

์ƒํƒœ๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ , DOM์„ ์ง์ ‘ ์ฐธ์กฐํ•˜์—ฌ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด

const inputRef = useRef();

const handleSubmit = (e) => {
  e.preventDefault();
  console.log(inputRef.current.value);
};

return (
  <form onSubmit={handleSubmit}>
    <input type="text" ref={inputRef} />
    <button type="submit">์ œ์ถœ</button>
  </form>
);

์žฅ์ 

  • ํผํฌ๋จผ์Šค์— ์ข‹๊ณ  ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•จ
  • ์ž…๋ ฅ์ฐฝ์ด ๋งŽ์„ ๋•Œ ๋ถ€๋‹ด์ด ์ ์Œ

๋‹จ์ 

  • ์ƒํƒœ ์ถ”์ ์ด ์–ด๋ ค์›€
  • validation์ด๋‚˜ ์ œ์–ด๊ฐ€ ๊นŒ๋‹ค๋กœ์›€

โœ… ์–ธ์ œ ์–ด๋–ค ๊ฑธ ์จ์•ผ ํ• ๊นŒ?

์ƒํ™ฉ์ถ”์ฒœ ๋ฐฉ์‹
์ž…๋ ฅ๊ฐ’์„ ์ œ์–ดํ•ด์•ผ ํ•จ (์œ ํšจ์„ฑ๊ฒ€์‚ฌ ๋“ฑ)Controlled
๋‹จ์ˆœ ์ž…๋ ฅ๋งŒ ๋ฐ›๊ณ  ์ œ์ถœํ•  ๊ฒฝ์šฐUncontrolled
์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Formik, React Hook Form ๋“ฑ) ์‚ฌ์šฉ๋‘˜ ๋‹ค ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

๐Ÿ“ ๋‚ด๊ฐ€ ๋А๋‚€ ์ 

์ฒ˜์Œ์—๋Š” ๋ฌด์กฐ๊ฑด Controlled ๋ฐฉ์‹์œผ๋กœ๋งŒ ํผ์„ ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ,
์ƒ๊ฐ๋ณด๋‹ค input์ด ๋งŽ์•„์ง€๋ฉด ์ฝ”๋“œ๋„ ๋ณต์žกํ•ด์ง€๊ณ  ๋ฆฌ๋ Œ๋”๋ง๋„ ๋งŽ์•„์ง€๋Š” ๊ฑธ ๋А๊ผˆ๋‹ค.
ํŠนํžˆ useRef๋ฅผ ์“ฐ๋ฉด ์„ฑ๋Šฅ ์ตœ์ ํ™”๋‚˜ ๊ฐ„๋‹จํ•œ ์ž…๋ ฅ ์ฒ˜๋ฆฌ์— ๊ฝค ์œ ์šฉํ•˜๋‹ค๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋๋‹ค.


๐Ÿง  โ€œํผ์€ ๋‹จ์ˆœํ•ด ๋ณด์—ฌ๋„ ๋ณต์žกํ•œ ์ธํ„ฐ๋ž™์…˜์ด ๋งŽ๋‹ค. ์ƒํƒœ๋ฅผ ์ œ์–ดํ• ์ง€ ๋ง์ง€๋ฅผ ๋จผ์ € ๊ณ ๋ฏผํ•˜์ž.โ€

profile
๊ฐœ๋ฐœ์ž๋กœ ์ทจ์—…์„ ์ค€๋น„ ์ค‘ ์ด๋ฉฐ, ์—ด์‹ฌํžˆ ๊ณต๋ถ€ ์ค‘ ์ž…๋‹ˆ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€