<select> ๋‚ด์žฅ ์ปดํฌ๋„ŒํŠธ๋Š” ์˜ต์…˜์„ ํฌํ•จํ•˜๋Š” select box๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>

๋ ˆํผ๋Ÿฐ์Šค

<select>

select box๋ฅผ ํ‘œ์‹œํ•˜๋ ค๋ฉด <select> ๋‚ด์žฅ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

<select>
<option value="someOption">Some option</option>
<option value="otherOption">Other option</option>
</select>

์•„๋ž˜ ๋” ๋งŽ์€ ์˜ˆ์‹œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Props

<select>๋Š” ์ผ๋ฐ˜์ ์ธ ์—˜๋ฆฌ๋จผํŠธ props๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

select box๋ฅผ ์ œ์–ดํ•˜๋ ค๋ฉด value prop์„ ์ „๋‹ฌํ•ด ์ฃผ์„ธ์š”.

  • value : String ํƒ€์ž… (๋˜๋Š” multiple={true}์—์„œ ์‚ฌ์šฉํ•˜๋Š” String ๋ฐฐ์—ด)์ด๋ฉฐ ์–ด๋–ค ์˜ต์…˜์„ ์„ ํƒํ• ์ง€ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. value๋Š” <select> ๋‚ด๋ถ€์— ์ค‘์ฒฉ๋œ <option>์˜ value์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

value๋ฅผ ์ „๋‹ฌํ•  ๋•Œ, ์ „๋‹ฌ๋œ value๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” onChange ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ <select>๊ฐ€ ์ œ์–ด๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, defaultValue prop์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

<select> props๋Š” ์ œ์–ด๋˜์ง€ ์•Š๋Š” ์ƒํƒœ์™€ ์ œ์–ด๋˜๋Š” ์ƒํƒœ ๋ชจ๋‘์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • autoComplete: String ํƒ€์ž…์ด๋ฉฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ž๋™ ์™„์„ฑ ๋™์ž‘ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • autoFocus: boolean ํƒ€์ž…์ด๋ฉฐ true๋ผ๋ฉด React๋Š” ๋งˆ์šดํŠธ ์‹œ ์—˜๋ฆฌ๋จผํŠธ์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค.
  • children: <select>๋Š” <option>, <optgroup> ๊ทธ๋ฆฌ๊ณ  <datalist>์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ—ˆ์šฉ๋œ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ „๋‹ฌํ•ด ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <option> ํƒœ๊ทธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ, ๊ฐ <option>์—๋Š” value๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • disabled: boolean ํƒ€์ž…์ด๋ฉฐ true๋ผ๋ฉด select box์™€๋Š” ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์—†๊ณ  ํ๋ฆฟํ•˜๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค.
  • form: String ํƒ€์ž…์ด๋ฉฐ select box์— ์†ํ•œ <form>์˜ id๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ƒ๋žตํ•˜๋ฉด ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ํผ์˜ id๊ฐ€ ์ง€์ •๋ฉ๋‹ˆ๋‹ค.
  • multiple: boolean ํƒ€์ž…์ด๋ฉฐ true๋ผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ๋‹ค์ค‘ ์„ ํƒ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • name: String ํƒ€์ž…์ด๋ฉฐ select box์˜ ํผ์„ ์ œ์ถœํ•  ๋•Œ ์ œ์ถœ๋˜๋Š” ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • onChange: Event ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ œ์–ด๋˜์–ด์•ผ ํ•˜๋Š” select box์ธ ๊ฒฝ์šฐ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์ฆ‰์‹œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์˜ input ์ด๋ฒคํŠธ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • onChangeCapture: onChange์™€ ๊ฐ™์ง€๋งŒ ์บก์ฒ˜ ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • onInput: Event ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์ฆ‰์‹œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. React์—์„œ๋Š” onChange๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ด€์Šต์ด์ง€๋งŒ, onInput๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • onInputCapture: onInput์™€ ๊ฐ™์ง€๋งŒ ์บก์ฒ˜ ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • onInvalid: Event ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ํผ ์ œ์ถœ ์‹œ ์ž…๋ ฅ์ด ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ๋œ invalid ์ด๋ฒคํŠธ์™€ ๋‹ฌ๋ฆฌ Reactdml onInvalid ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง๋ฉ๋‹ˆ๋‹ค.
  • onInvalidCapture: onInvalid์™€ ๊ฐ™์ง€๋งŒ ์บก์ฒ˜ ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • required: boolean ํƒ€์ž…์ด๋ฉฐ true๋ผ๋ฉด ํผ ์ œ์ถœ ์‹œ ๊ฐ’์„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • size: ์ˆซ์ž ํƒ€์ž…์ด๋ฉฐ multiple={true}์ธ ๊ฒฝ์šฐ ์ฒ˜์Œ ๋ณด์—ฌ์ง€๋Š” ์•„์ดํ…œ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • HTML๊ณผ๋Š” ๋‹ฌ๋ฆฌ, selected ์†์„ฑ์„ <option>์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ์ œ์–ด๋˜์ง€ ์•Š๋Š” select box์ธ ๊ฒฝ์šฐ <select defaultValue>๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ œ์–ด๋˜์–ด์•ผ ํ•˜๋Š” select box์ธ ๊ฒฝ์šฐ <select value>๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • <select>์— value prop์ด ์ „๋‹ฌ๋œ๋‹ค๋ฉด, ์ œ์–ด๋˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.
  • select box๋Š” ์ œ์–ด ์ƒํƒœ์™€ ๋น„์ œ์–ด ์ƒํƒœ๋ฅผ ๋™์‹œ์— ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ ์ƒํƒœ๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • select box๋Š” ์ƒ๋ช… ์ฃผ๊ธฐ ๋™์•ˆ ์ฒ˜์Œ ์„ค์ •ํ•œ ์ œ์–ด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ œ์–ด๋˜๋Š” ๋ชจ๋“  select box๋Š” ์ œ๊ณต๋˜๋Š” ๊ฐ’์„ ๋™๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋Š” onChange ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

์˜ต์…˜์ด ๋‹ด๊ธด select box ํ‘œ์‹œ

<select>๋Š” <option> ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” <select>๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๊ฐ <option>์—๋Š” ํผ๊ณผ ํ•จ๊ป˜ ์ œ์ถœ๋˜๋Š” ๋ฐ์ดํ„ฐ์ธ value๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}


select box๊ฐ€ ํฌํ•จ๋œ ๋ผ๋ฒจ ์ œ๊ณต

๋ผ๋ฒจ์ด ํ•ด๋‹น select box์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Œ์„ ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด <label> ํƒœ๊ทธ ์•ˆ์— <select>๋ฅผ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ผ๋ฒจ์„ ํด๋ฆญํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์ž๋™์œผ๋กœ ์„ ํƒ ์ƒ์ž์— ์ดˆ์ ์„ ๋งž์ถฅ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ select box์— ์ดˆ์ ์„ ๋งž์ถ”๋ฉด ์Šคํฌ๋ฆฐ ๋ฆฌ๋”๊ฐ€ ๋ผ๋ฒจ ์บก์…˜์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.

<select>๋ฅผ <label> ์•ˆ์— ์ค‘์ฒฉ ์‹œํ‚ฌ ์ˆ˜ ์—†๋‹ค๋ฉด, ๊ฐ™์€ ID๋ฅผ <select id>์™€ <label htmlFor>์— ์ „๋‹ฌํ•˜์—ฌ ์—ฐ๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค ๊ฐ„ ์ถฉ๋Œ์„ ํ”ผํ•˜๋ ค๋ฉด useId๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ID๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ์„ธ์š”.

import { useId } from 'react';

export default function Form() {
  const vegetableSelectId = useId();
  return (
    <>
      <label>
        Pick a fruit:
        <select name="selectedFruit">
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <hr />
      <label htmlFor={vegetableSelectId}>
        Pick a vegetable:
      </label>
      <select id={vegetableSelectId} name="selectedVegetable">
        <option value="cucumber">Cucumber</option>
        <option value="corn">Corn</option>
        <option value="tomato">Tomato</option>
      </select>
    </>
  );
}


์ดˆ๊ธฐ ์„ ํƒ ์˜ต์…˜ ์ œ๊ณต

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ชฉ๋ก์—์„œ ์ฒซ ๋ฒˆ์งธ <option>์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์˜ต์…˜์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ ํƒํ•˜๋ ค๋ฉด <select> ์—˜๋ฆฌ๋จผํŠธ์— <option>์˜ value๋ฅผ defaultValue๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

export default function FruitPicker() {
  return (
    <label>
      Pick a fruit:
      <select name="selectedFruit" defaultValue="orange">
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}

Pitfall

HTML๊ณผ๋Š” ๋‹ฌ๋ฆฌ ๊ฐœ๋ณ„ <option>์— selected ์†์„ฑ์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


๋‹ค์ค‘ ์„ ํƒ ํ™œ์„ฑํ™”

์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌ ์˜ต์…˜์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก <select>์— multiple={true}๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ์„ ํƒ ์˜ต์…˜์„ ์„ ํƒํ•˜๋ ค๋ฉด defaultValue๋ฅผ ๋ฐฐ์—ด๋กœ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

export default function FruitPicker() {
  return (
    <label>
      Pick some fruits:
      <select
        name="selectedFruit"
        defaultValue={['orange', 'banana']}
        multiple={true}
      >
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}


ํผ์„ ์ œ์ถœํ•  ๋•Œ ์„ ํƒ ์ƒ์ž์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐ’ ์ฝ๊ธฐ

๋‚ด๋ถ€์— <button type="submit">์ด ์žˆ๋Š” select box ์ฃผ๋ณ€์— <form>์„ ์ถ”๊ฐ€ํ•˜๋ฉด <form onSubmit> ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•ด ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋Ÿฐ ์„ค์ •์ด ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์–‘์‹ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜„์žฌ URL๋กœ ๋ณด๋‚ด๊ณ  ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ ๊ณ ์นฉ๋‹ˆ๋‹ค. e.preventDefault()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น ๋™์ž‘์„ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. new FormData(e.target)๋กœ ์–‘์‹ ๋ฐ์ดํ„ฐ ์ฝ๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

export default function EditPost() {
  function handleSubmit(e) {
    // ๋ธŒ๋ผ์šฐ์ €์—์„œ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค์‹œ ๋กœ๋“œ๋˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    e.preventDefault();
    // ํผ ๋ฐ์ดํ„ฐ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    const form = e.target;
    const formData = new FormData(form);
    // formData๋ฅผ ๊ฐ€์ ธ์˜จ ๋ณธ๋ฌธ์œผ๋กœ ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    fetch('/some-api', { method: form.method, body: formData });
    // ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ URL์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    console.log(new URLSearchParams(formData).toString());
    // ์ผ๋ฐ˜ ์˜ค๋ธŒ์ ํŠธ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson); // (!) ์—ฌ๊ธฐ์—๋Š” ๋‘ ๊ฐœ ์ด์ƒ์˜ ์„ ํƒ ๊ฐ’์ด ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    // ๋˜๋Š” ์ด๋ฆ„-๊ฐ’ ์Œ์˜ ๋ฐฐ์—ด์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    console.log([...formData.entries()]);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Pick your favorite fruit:
        <select name="selectedFruit" defaultValue="orange">
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <label>
        Pick all your favorite vegetables:
        <select
          name="selectedVegetables"
          multiple={true}
          defaultValue={['corn', 'tomato']}
        >
          <option value="cucumber">Cucumber</option>
          <option value="corn">Corn</option>
          <option value="tomato">Tomato</option>
        </select>
      </label>
      <hr />
      <button type="reset">Reset</button>
      <button type="submit">Submit</button>
    </form>
  );
}

Note

<select>์— name์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.(์˜ˆ์‹œ : <select name="selectedFruit" />) ์ง€์ •ํ•œ name์€ ํผ ๋ฐ์ดํ„ฐ์—์„œ ํ‚ค๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (์˜ˆ์‹œ : { selectedFruit: "orange" })

<select multiple={true}>๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด FormData์—์„œ ๊ฐ ์„ ํƒํ•œ ๊ฐ’์„ ๋ณ„๋„์˜ ์ด๋ฆ„-๊ฐ’ ์Œ์œผ๋กœ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์˜ˆ์‹œ์—์„œ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.

Pitfall

๊ธฐ๋ณธ์ ์œผ๋กœ <form> ๋‚ด๋ถ€์˜ ๋ชจ๋“  <button>์€ select box์˜ ๊ฐ’์„ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค. ์˜๋„์น˜ ์•Š์€ ๋™์ž‘์œผ๋กœ ์ธํ•ด ๋‹นํ™ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! React ์ปดํฌ๋„ŒํŠธ์˜ ์‚ฌ์šฉ์ž ์ •์˜ Button์ด ์žˆ๋‹ค๋ฉด <button> ๋Œ€์‹  <button type="button">์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ช…์‹œ์ ์œผ๋กœ ํผ์„ ์ œ์ถœํ•ด์•ผ ํ•˜๋Š” ๊ณณ์— <button type="submit">์„ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”.


์ƒํƒœ ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ select box ์ œ์–ด

<select>์™€ ๊ฐ™์€ select box๋Š” ์ œ์–ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. <select defaultValue="orange" />์™€ ๊ฐ™์ด ์ฒ˜์Œ์— ์„ ํƒํ•œ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋”๋ผ๋„ JSX๋Š” ํ˜„์žฌ ๊ฐ’์ด ์•„๋‹Œ ์ดˆ๊ธฐ ๊ฐ’๋งŒ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ œ์–ด๋œ select box๋ฅผ ๋ Œ๋”๋งํ•˜๋ ค๋ฉด value prop์„ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React๋Š” select box๊ฐ€ ํ•ญ์ƒ ์ „๋‹ฌํ•œ value๋ฅผ ๊ฐ–๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต ์ƒํƒœ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜์—ฌ ์„ ํƒ ์ƒ์ž๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.

function FruitPicker() {
const [selectedFruit, setSelectedFruit] = useState('orange'); // ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
// ...
return (
<select
value={selectedFruit} // ...์„ ํƒ์˜ ๊ฐ’์ด ์ƒํƒœ ๋ณ€์ˆ˜์™€ ์ผ์น˜ํ•˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค....
onChange={e => setSelectedFruit(e.target.value)} // ... ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ด ์ฃผ์„ธ์š”!
>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
<option value="orange">Orange</option>
</select>
);
}

๋ชจ๋“  ์„ ํƒ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ UI ์ผ๋ถ€๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

import { useState } from 'react';

export default function FruitPicker() {
  const [selectedFruit, setSelectedFruit] = useState('orange');
  const [selectedVegs, setSelectedVegs] = useState(['corn', 'tomato']);
  return (
    <>
      <label>
        Pick a fruit:
        <select
          value={selectedFruit}
          onChange={e => setSelectedFruit(e.target.value)}
        >
          <option value="apple">Apple</option>
          <option value="banana">Banana</option>
          <option value="orange">Orange</option>
        </select>
      </label>
      <hr />
      <label>
        Pick all your favorite vegetables:
        <select
          multiple={true}
          value={selectedVegs}
          onChange={e => {
            const options = [...e.target.selectedOptions];
            const values = options.map(option => option.value);
            setSelectedVegs(values);
          }}
        >
          <option value="cucumber">Cucumber</option>
          <option value="corn">Corn</option>
          <option value="tomato">Tomato</option>
        </select>
      </label>
      <hr />
      <p>Your favorite fruit: {selectedFruit}</p>
      <p>Your favorite vegetables: {selectedVegs.join(', ')}</p>
    </>
  );
}

Pitfall

onChange ์—†์ด value๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ์˜ต์…˜์„ ์„ ํƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. value๋ฅผ ์ „๋‹ฌํ•˜์—ฌ select box๋ฅผ ์ œ์–ดํ•˜๋ฉด ์ „๋‹ฌํ•œ ๊ฐ’์ด ํ•ญ์ƒ ์žˆ๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ value๋ฅผ ์ƒํƒœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ–ˆ์ง€๋งŒ onChange ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์œผ๋ฉด React๋Š” ํ‚ค๋ฅผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค select box๋ฅผ ์ง€์ •ํ•œ value๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.

HTML๊ณผ๋Š” ๋‹ฌ๋ฆฌ ๊ฐœ๋ณ„ <option>์— selected ์†์„ฑ์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.