[๐ŸŽ์ฝ”๋”ฉ์• ํ”Œ ๊ฐ•์˜์š”์•ฝ]React์—์„œ input ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌํ•˜๊ธฐโŒจ๏ธ

๐ŸŒˆ KJยท2025๋…„ 5์›” 17์ผ

codingapple

๋ชฉ๋ก ๋ณด๊ธฐ
11/23
post-thumbnail

input ๊ธฐ๋ณธ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ ๐Ÿงฉ

๋‹ค์–‘ํ•œ ์ž…๋ ฅ ํƒœ๊ทธ๋“ค ๐Ÿ“‹

<input type="text"/>     // ํ…์ŠคํŠธ ์ž…๋ ฅ
<input type="range"/>    // ์Šฌ๋ผ์ด๋”
<input type="date"/>     // ๋‚ ์งœ ์„ ํƒ
<input type="number"/>   // ์ˆซ์ž ์ž…๋ ฅ
<textarea></textarea>    // ์—ฌ๋Ÿฌ ์ค„ ํ…์ŠคํŠธ
<select></select>        // ๋“œ๋กญ๋‹ค์šด ์„ ํƒ
  • ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ input ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๐ŸŽ›๏ธ

์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ๋‹ค๋ฃจ๊ธฐ ๐Ÿ› ๏ธ

input ๋ณ€๊ฒฝ ๊ฐ์ง€ํ•˜๊ธฐ ๐Ÿ”„

<input onChange={()=>{ ์‹คํ–‰ํ• ์ฝ”๋“œ }}/>
  • onChange ๋˜๋Š” onInput: ์ž…๋ ฅ๊ฐ’ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ฝ”๋“œ ์‹คํ–‰ ๐Ÿ“Š
  • ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ: onMouseOver, onScroll ๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ์กด์žฌ ๐Ÿ–ฑ๏ธ

์ž…๋ ฅ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ ๐Ÿ“ฅ

<input onChange={(e)=>{ console.log(e.target.value) }}/>
  • ์ด๋ฒคํŠธ ๊ฐ์ฒด e๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ์ž…๋ ฅ๊ฐ’์— ์ ‘๊ทผ ๐Ÿ“
  • e.target.value: ํ˜„์žฌ input์— ์ž…๋ ฅ๋œ ๊ฐ’ ๐Ÿ“„
  • ์ด๋ฒคํŠธ ๊ฐ์ฒด์˜ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ๋“ค:
    • e.target: ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์†Œ
    • e.preventDefault(): ๊ธฐ๋ณธ ๋™์ž‘ ๋ฐฉ์ง€
    • e.stopPropagation(): ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ๋ฐฉ์ง€

์ž…๋ ฅ ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ ๐Ÿ’พ

state์— ์ž…๋ ฅ๊ฐ’ ์ €์žฅ ๐Ÿ”„

function App() {
  let [์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ] = useState('');
  return (
    <input onChange={(e)=>{ 
      ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ(e.target.value);
      console.log(์ž…๋ ฅ๊ฐ’);
    }} />
  )
}
  • ๋นˆ ๋ฌธ์ž์—ด('')๋กœ state ์ดˆ๊ธฐํ™” ๐Ÿ” 
  • onChange ์ด๋ฒคํŠธ์—์„œ ์ž…๋ ฅ๊ฐ’์„ state๋กœ ์—…๋ฐ์ดํŠธ ๐Ÿ”„
  • ์ฃผ์˜: setState ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋จ โš ๏ธ
    • console.log๊ฐ€ state ์—…๋ฐ์ดํŠธ ์ „์— ์‹คํ–‰๋˜์–ด ํ•œ ๊ธ€์ž ๋’ค์ณ์ง„ ๊ฐ’ ์ถœ๋ ฅ

์‘์šฉ: ๋ธ”๋กœ๊ทธ ๊ธ€ ์ถ”๊ฐ€/์‚ญ์ œ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๐Ÿ“

๊ธ€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ โž•

function App() {
  let [๊ธ€์ œ๋ชฉ, ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  let [์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ] = useState('');

  return (
    <div>
      <div className="publish">
        <input onChange={(e)=>{ ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ(e.target.value) }} />
        <button onClick={()=>{ 
          // 1. ๊ธฐ์กด ๊ธ€์ œ๋ชฉ ๋ฐฐ์—ด ๋ณต์‚ฌ
          let copy = [...๊ธ€์ œ๋ชฉ]; 
          // 2. ๋ณต์‚ฌํ•œ ๋ฐฐ์—ด์— ์ƒˆ ๊ธ€ ์ถ”๊ฐ€
          copy.unshift(์ž…๋ ฅ๊ฐ’);
          // 3. state ์—…๋ฐ์ดํŠธ
          ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ(copy);
          // 4. input ์ดˆ๊ธฐํ™”
          ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ('');
        }}>๋ฐœํ–‰</button>
      </div>
      
      {/* ๊ธ€ ๋ชฉ๋ก ํ‘œ์‹œ */}
      {
        ๊ธ€์ œ๋ชฉ.map(function(a, i) {
          return (
            <div className="list" key={i}>
              <h4>{a}</h4>
              <p>2์›” 18์ผ ๋ฐœํ–‰</p>
            </div>
          )
        })
      }
    </div>
  )
}

๊ธ€ ์‚ญ์ œ ๊ธฐ๋Šฅ ๊ตฌํ˜„ โž–

function App() {
  let [๊ธ€์ œ๋ชฉ, ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  let [์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ] = useState('');

  return (
    <div>
      {/* ์ž…๋ ฅ ๋ถ€๋ถ„ ์ƒ๋žต */}
      
      {/* ๊ธ€ ๋ชฉ๋ก๊ณผ ์‚ญ์ œ ๋ฒ„ํŠผ */}
      {
        ๊ธ€์ œ๋ชฉ.map(function(a, i) {
          return (
            <div className="list" key={i}>
              <h4>{a}</h4>
              <p>2์›” 18์ผ ๋ฐœํ–‰</p>
              <button onClick={()=>{ 
                // 1. ๊ธฐ์กด ๋ฐฐ์—ด ๋ณต์‚ฌ
                let copy = [...๊ธ€์ œ๋ชฉ]; 
                // 2. i๋ฒˆ์งธ ์š”์†Œ ์‚ญ์ œ
                copy.splice(i, 1); 
                // 3. state ์—…๋ฐ์ดํŠธ
                ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ(copy);
              }}>์‚ญ์ œ</button>
            </div>
          )
        })
      }
    </div>
  )
}

๊ฐ•์˜ ๋‚ด์šฉ ๊ฒ€ํ†  ๐Ÿ”

Claude.ai ์—์„œ ์ œ์‹œํ•œ ๊ฐ•์˜์—์„œ ๋ณด์ถฉํ•˜๋ฉด ์ข‹์€ ๋‚ด์šฉ

  1. ๋ฆฌ์•กํŠธ ๋ฐฉ์‹ ์„ค๋ช… ๋ถ€์กฑ: ๊ฐ•์˜์—์„œ๋Š” input ์ฒ˜๋ฆฌ๊ฐ€ ์ผ๋ฐ˜ JavaScript์™€ ๋น„์Šทํ•˜๋‹ค๊ณ  ์„ค๋ช…ํ•˜์ง€๋งŒ, React์—์„œ ๊ถŒ์žฅํ•˜๋Š” ์ œ์–ด ์ปดํฌ๋„ŒํŠธ(Controlled Component) ๊ฐœ๋…์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. โš ๏ธ

  2. ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ ๋ˆ„๋ฝ: input์˜ value ์†์„ฑ์„ state์™€ ์—ฐ๊ฒฐํ•˜์—ฌ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ž…๋ ฅ ํ•„๋“œ ์ดˆ๊ธฐํ™”๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ”„

  3. ํผ ์ œ์ถœ ์ฒ˜๋ฆฌ ๋ฏธ์„ค๋ช…: ์ผ๋ฐ˜์ ์œผ๋กœ ์ž…๋ ฅ์€ ํผ ๋‚ด์—์„œ ์ด๋ฃจ์–ด์ง€๋ฉฐ, onSubmit ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•๊ณผ ํผ ๊ธฐ๋ณธ ๋™์ž‘ ๋ฐฉ์ง€(e.preventDefault())์— ๋Œ€ํ•œ ์‹ค์ œ ํ™œ์šฉ ์˜ˆ์‹œ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ“

์ถ”๊ฐ€ ์ •๋ณด ๋ฐ ํŒ ๐Ÿ’ก

์ œ์–ด ์ปดํฌ๋„ŒํŠธ(Controlled Component) ๊ตฌํ˜„ ๐ŸŽฎ

function App() {
  let [๊ธ€์ œ๋ชฉ, ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  let [์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ] = useState('');

  return (
    <div>
      <div className="publish">
        {/* value ์†์„ฑ์„ state์™€ ์—ฐ๊ฒฐ */}
        <input 
          value={์ž…๋ ฅ๊ฐ’} 
          onChange={(e)=>{ ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ(e.target.value) }} 
        />
        <button onClick={()=>{ 
          // ๋นˆ ๊ฐ’์ด ์•„๋‹ ๋•Œ๋งŒ ์ถ”๊ฐ€
          if (์ž…๋ ฅ๊ฐ’.trim() !== '') {
            let copy = [...๊ธ€์ œ๋ชฉ]; 
            copy.unshift(์ž…๋ ฅ๊ฐ’);
            ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ(copy);
            ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ(''); // input ์ดˆ๊ธฐํ™” ์ž‘๋™
          }
        }}>๋ฐœํ–‰</button>
      </div>
      
      {/* ๋‚˜๋จธ์ง€ ์ฝ”๋“œ ์ƒ๋žต */}
    </div>
  )
}
  • value={์ž…๋ ฅ๊ฐ’}: input์˜ ๊ฐ’์„ state์™€ ์—ฐ๊ฒฐํ•˜์—ฌ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ ๊ตฌํ˜„ ๐Ÿ”„
  • ์ž…๋ ฅ๊ฐ’ ์ดˆ๊ธฐํ™” ๊ฐ€๋Šฅ ๋ฐ state ๊ธฐ๋ฐ˜ ์ž…๋ ฅ๊ฐ’ ์ œ์–ด ๊ฐ€๋Šฅ โœ…

ํผ ์ œ์ถœ ํ™œ์šฉํ•˜๊ธฐ ๐Ÿ“‹

function App() {
  let [๊ธ€์ œ๋ชฉ, ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  let [์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ] = useState('');

  // ํผ ์ œ์ถœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
  const handleSubmit = (e) => {
    e.preventDefault(); // ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ ๋ฐฉ์ง€
    
    if (์ž…๋ ฅ๊ฐ’.trim() !== '') {
      let copy = [...๊ธ€์ œ๋ชฉ]; 
      copy.unshift(์ž…๋ ฅ๊ฐ’);
      ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ(copy);
      ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ('');
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input 
          value={์ž…๋ ฅ๊ฐ’} 
          onChange={(e)=>{ ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ(e.target.value) }} 
        />
        <button type="submit">๋ฐœํ–‰</button>
      </form>
      
      {/* ๋‚˜๋จธ์ง€ ์ฝ”๋“œ ์ƒ๋žต */}
    </div>
  )
}
  • onSubmit ์ด๋ฒคํŠธ ์‚ฌ์šฉ์œผ๋กœ Enter ํ‚ค ์ž…๋ ฅ์œผ๋กœ๋„ ์ œ์ถœ ๊ฐ€๋Šฅ โŒจ๏ธ
  • e.preventDefault()๋กœ ํผ ์ œ์ถœ ์‹œ ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ ๋ฐฉ์ง€ โš ๏ธ

์ž…๋ ฅ๊ฐ’ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ถ”๊ฐ€ โœ…

function App() {
  let [๊ธ€์ œ๋ชฉ, ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ] = useState(['๋‚จ์ž์ฝ”ํŠธ ์ถ”์ฒœ', '๊ฐ•๋‚จ ์šฐ๋™๋ง›์ง‘', 'ํŒŒ์ด์ฌ๋…ํ•™']);
  let [์ž…๋ ฅ๊ฐ’, ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ] = useState('');
  let [์˜ค๋ฅ˜๋ฉ”์‹œ์ง€, ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๋ณ€๊ฒฝ] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    
    // ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
    if (์ž…๋ ฅ๊ฐ’.trim() === '') {
      ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๋ณ€๊ฒฝ('๊ธ€ ์ œ๋ชฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”');
      return;
    }
    
    if (์ž…๋ ฅ๊ฐ’.length > 20) {
      ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๋ณ€๊ฒฝ('๊ธ€ ์ œ๋ชฉ์€ 20์ž ์ด๋‚ด๋กœ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”');
      return;
    }
    
    // ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ†ต๊ณผ ์‹œ
    let copy = [...๊ธ€์ œ๋ชฉ]; 
    copy.unshift(์ž…๋ ฅ๊ฐ’);
    ๊ธ€์ œ๋ชฉ๋ณ€๊ฒฝ(copy);
    ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ('');
    ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๋ณ€๊ฒฝ('');
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input 
          value={์ž…๋ ฅ๊ฐ’} 
          onChange={(e)=>{ 
            ์ž…๋ ฅ๊ฐ’๋ณ€๊ฒฝ(e.target.value);
            ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๋ณ€๊ฒฝ(''); // ์ž…๋ ฅ ์‹œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ดˆ๊ธฐํ™”
          }} 
        />
        <button type="submit">๋ฐœํ–‰</button>
        {์˜ค๋ฅ˜๋ฉ”์‹œ์ง€ && <p className="error">{์˜ค๋ฅ˜๋ฉ”์‹œ์ง€}</p>}
      </form>
      
      {/* ๋‚˜๋จธ์ง€ ์ฝ”๋“œ ์ƒ๋žต */}
    </div>
  )
}
  • ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ถ”๊ฐ€ ๐Ÿ›ก๏ธ
  • ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต ๐Ÿ’ฌ
  • ์ž…๋ ฅ ์‹œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ดˆ๊ธฐํ™”๋กœ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„  ๐Ÿ‘

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