๐ŸŽจ 08. useRef: ๋ Œ๋”๋ง์„ ํ”ผํ•˜๋Š” ๋น„๋ฐ€ ๊ธˆ๊ณ 

2026๋…„ 4์›” 30์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

ํ•ญ์ƒ ์ตœ์‹  ๊ฐ’์„ ์œ ์ง€ํ•ด์•ผ ํ•˜์ง€๋งŒ ํ™”๋ฉด์ด ๋ฆฌ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์€ ์›์น˜ ์•Š์„ ๋•Œ, useRef๊ฐ€ ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ๋‚ด๋ถ€ ์›๋ฆฌ์™€ ํ•จ๊ป˜ ํŒŒํ—ค์นฉ๋‹ˆ๋‹ค.

๐ŸŽฏ ์ด ์„น์…˜์„ ์ฝ๊ณ  ๋‚˜๋ฉด:

  • useRef๊ฐ€ ๋‹จ์ˆœํžˆ <input> ์ฐฝ์— ํฌ์ปค์Šค๋ฅผ ๋งž์ถ”๋Š” DOM ์—ฐ๊ฒฐ ๋„๊ตฌ๊ฐ€ ์•„๋‹˜์„ ์•Œ๊ฒŒ ๋œ๋‹ค.
  • ์ƒํƒœ(useState)์™€ ์ฐธ์กฐ(useRef)์˜ ๋ณธ์งˆ์ ์ธ ๊ธฐ์ˆ ์  ์ฐจ์ด๋ฅผ ์Šค๋ƒ…์ƒท vs ์˜๊ตฌ ๋ณ€์ˆ˜ ๋ฉ˜ํƒˆ ๋ชจ๋ธ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ™”๋ฉด ์—…๋ฐ์ดํŠธ ์—†์ด ๋ถˆ๋ณ€ํ•˜๋Š” ๊ฐ’์„ ์€๋ฐ€ํžˆ ์ถ”์ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ(ํƒ€์ด๋จธ ID ์ €์žฅ, ์ด์ „ ์ƒํƒœ ์ถ”์ ) useRef๋ฅผ ํ›Œ๋ฅญํ•˜๊ฒŒ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 10๋ถ„ / ํ•ต์‹ฌ ํŒŒํŠธ: 7๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ์˜์ฒ (์‹ ์ž…): "ํƒ€์ด๋จธ ์Šคํ†ฑ์›Œ์น˜๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ๋Š”๋ฐ์š”! ์‹œ์ž‘ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €๋Š”๋ฐ ์ค‘์ง€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ํƒ€์ด๋จธ๊ฐ€ ์•ˆ ๋ฉˆ์ถ”๊ณ  ๊ณ„์† ๊ฐ€์š”! ์ธํ„ฐ๋ฒŒ ์•„์ด๋””(ID)๋ฅผ useState์— ๋‹ด์•„๋’€๋Š”๋ฐ ๋ญ๊ฐ€ ๋ฌธ์ œ์ฃ ?"
  • ์˜ํ˜ธ(๋ฆฌ๋“œ): "์˜์ฒ  ๋‹˜, ํ™”๋ฉด์— ๊ทธ ์ˆซ์ž ๋ณด์—ฌ์ฃผ์‹ค ๊ฑด๊ฐ€์š”? ์•ˆ ๋ณด์—ฌ์ค„ ๋ณ€์ˆ˜๋ผ๋ฉด ๊ณผ๋„ํ•œ ๋ Œ๋”๋ง(useState) ํ„ฐ๋œจ๋ฆฌ์ง€ ๋ง๊ณ  ์กฐ์šฉํžˆ ๋’ท์ฃผ๋จธ๋‹ˆ(useRef)์— ๋„ฃ๊ณ  ๋‹ค๋‹ˆ๋ผ๊ณ  ์˜ˆ์ „์— ๋ง์”€๋“œ๋ ธ์„ ํ…๋ฐ์š”."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€: ์š”๋™์น˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฒฌ๋””๋Š” ๋‹ป

๋Œ€๋ถ€๋ถ„์˜ React ์˜ˆ์ œ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด useRef๋ฅผ ์ฒ˜์Œ ์†Œ๊ฐœํ•  ๋•Œ ๊ผญ "DOM ์กฐ์ž‘(<input ref={myRef}>)์„ ์œ„ํ•œ ๊ฐˆ๊ณ ๋ฆฌ์ž…๋‹ˆ๋‹ค~" ๋ผ๊ณ  ๊ฐ€๋ฅด์ณ. ํ•˜์ง€๋งŒ ์ด๊ฑด useRef ๋Šฅ๋ ฅ์น˜ ์ค‘ ๋น™์‚ฐ์˜ ์ผ๊ฐ๋„ ์•ˆ ๋˜๋Š” 10%์˜ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์— ๋ถˆ๊ณผํ•ด.

๐Ÿค” ์ž ๊น, ๋จผ์ € ์ƒ๊ฐํ•ด๋ด
์Šคํ†ฑ์›Œ์น˜ ์ฝ”๋“œ๋ฅผ ์งœ๋ ค๊ณ  ํ•ด. ํƒ€์ด๋จธ๋ฅผ ๋ฉˆ์ถ”๋ ค๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ clearInterval(์•„์ด๋””๊ณ ์œ ๋ฒˆํ˜ธ)๊ฐ€ ํ•„์š”ํ•˜์ง€.
์ด ๊ณ ์œ  ๋ฒˆํ˜ธ๋ฅผ ๋ Œ๋”๋ง ์‚ฌ์ดํด์ด ๋Œ์•„๋„ ๊ธฐ์–ตํ•˜๋ ค๋ฉด ์–ด๋””๋‹ค ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ• ๊นŒ?

// โŒ ์˜์ฒ ์ด์˜ ์œ„ํ—˜ํ•œ ์„ ํƒ (์ƒํƒœ ์˜ค๋‚จ์šฉ)
function Stopwatch() {
  const [seconds, setSeconds] = useState(0);
  const [timerId, setTimerId] = useState(null); // ๐Ÿšจ ํ™”๋ฉด์— ๊ทธ๋ฆฌ์ง€๋„ ์•Š์„ ๊ฑด๋ฐ ๊ตณ์ด ์ƒํƒœ๋กœ ๋งŒ๋“ฆ!
 
  const handleStart = () => {
    const id = setInterval(() => setSeconds(s => s + 1), 1000);
    setTimerId(id); // ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์ƒํƒœ ๊ฐฑ์‹  ๋ฐœ๋™! -> ๋ฌด์˜๋ฏธํ•œ ๋ Œ๋”๋ง 1ํšŒ ์ถ”๊ฐ€ ๋ฐœ์‚ฌ!
  };
 
  const handleStop = () => {
    clearInterval(timerId);
  };
 
  return (
    <div>
      <p>๊ฒฝ๊ณผ ์‹œ๊ฐ„: {seconds}์ดˆ</p>
      <button onClick={handleStart}>์‹œ์ž‘</button>
      <button onClick={handleStop}>๋ฉˆ์ถฐ!</button>
    </div>
  );
}

์˜์ฒ ์ด ์ฝ”๋“œ๋Š” ์–ผํ• ๋ฌธ์ œ๊ฐ€ ์—†์–ด ๋ณด์—ฌ(๊ตฌ๋™์€ ๋˜๋‹ˆ๊นŒ).
ํ•˜์ง€๋งŒ ์ด๊ฑด ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. timerId๋Š” ํ™”๋ฉด UI์˜ ํ”ฝ์…€ ๋‹จ ํ•˜๋‚˜๋„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋ฐ, ์–˜๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ต์‹œ๊ณ  setTimerId(id)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฆฌ์•กํŠธ๋Š” ์ƒํƒœ ๋ณ€๊ฒฝ์œผ๋กœ ๋ณด๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ ๋ฒˆ ๋” ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ์—๊ฒ "๊ฐ’์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅํ•˜๋˜, ๊ฐ’์ด ๋ฐ”๋€๋‹ค๊ณ  ๋ Œ๋”๋ง์„ ์š”์ฒญํ•˜์ง€๋Š” ์•Š๋Š” ๋น„๋ฐ€ ์ฐฝ๊ณ " ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒŒ ๋ฐ”๋กœ useRef์˜ ๋ณธ์งˆ์ž…๋‹ˆ๋‹ค.


๐Ÿ—๏ธ ๋น„์œ ๋กœ ๋จผ์ € ์ดํ•ดํ•˜๊ธฐ

๐Ÿง’ 5์‚ด์—๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค๋ฉด?

  1. useState๋Š” ๋ฐฉ์†ก๊ตญ ๋งˆ์ดํฌ์•ผ. ๋งˆ์ดํฌ์— ๋Œ€๊ณ  ์ˆซ์ž๋ฅผ ๋ฐ”๊พธ๋ฉด ์˜จ ๋™๋„ค ๋งˆ์„ ์‚ฌ๋žŒ๋“ค(์ปดํฌ๋„ŒํŠธ๋“ค)์ด ๋‹ค ๋ฆฌ์…‹๋ผ์„œ ๋‹ค์‹œ ๋“ค์œผ๋Ÿฌ ๊ด‘์žฅ์œผ๋กœ ๋ชจ์ด์ง€(๋ฆฌ๋ Œ๋”๋ง ํŒŒํ‹ฐ).

  2. useRef๋Š” ๋„ค ๋ฐ”์ง“๋‹จ ๊นŠ์ˆ™์ด ์ˆจ๊ฒจ๋†“์€ ์ž‘์€ ๊ธˆ๊ณ  ๋ฐ•์Šค(current ์†์„ฑ) ์•ผ.
    ๋„ค๊ฐ€ ๋ชฐ๋ž˜ ๊ธˆ๊ณ  ๋ฌธ์„ ์—ด๊ณ  current ๊ณต๊ฐ„ ์•ˆ์— ๋ˆ์„ 100๋งŒ ์›์œผ๋กœ ๋ฐ”๊พธ๋“  10์›์œผ๋กœ ์ชผ๊ฐœ๋“  ๋™๋„ค ์‚ฌ๋žŒ๋“ค์€ ์•„๋ฌด๋„ ๋ชจ๋ฅด๊ณ  ์•„๋ฌด ์†Œ๋ฆฌ๋„ ์•ˆ ๋‚˜(๋ฆฌ๋ Œ๋”๋ง ๋ฌด์‹œ).
    ํ•˜์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์–ด๋„, ๊ทธ ๋ฐ”์ง“๋‹จ ์† ๊ธˆ๊ณ  ์ƒ์ž๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ด์•„์žˆ๋Š” ๊ธฐ๊ฐ„ ๋‚ด๋‚ด ์˜๊ตฌ์ ์œผ๋กœ ๋ณด์กด๋˜๋ฉด์„œ ์ ˆ๋Œ€ ์ •๋ณด๊ฐ€ ์ฆ๋ฐœํ•˜์ง€ ์•Š์•„.

โœ… ํ•ต์‹ฌ ์›๋ฆฌ:
React ๊ณต์‹ ๋ฌธ์„œ์˜ ํ‘œํ˜„๋Œ€๋กœ, useRef๋Š” { current: initialValue } ํ˜•ํƒœ์˜ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋‹ค์Œ ๋ Œ๋”์—์„œ๋„ ๋Œ๋ ค์ค€๋‹ค. current๋Š” ์ง์ ‘ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด ๋ณ€๊ฒฝ์€ ์ƒํƒœ ๋ณ€๊ฒฝ ์‹ ํ˜ธ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— React๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋ž˜์„œ useRef๋Š” ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๋Š” ๊ฐ’์— ์–ด์šธ๋ฆฐ๋‹ค. ํƒ€์ด๋จธ ID, ์ด์ „ ์Šคํฌ๋กค ์œ„์น˜, DOM ๋…ธ๋“œ์ฒ˜๋Ÿผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋‚˜ Effect์—์„œ ์ฝ๊ณ  ์“ฐ๋Š” ๊ฐ’์€ ์ข‹์ง€๋งŒ, ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ๊ฐ’์€ useState๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.


๐Ÿงฉ ์‹ค์ „ ๋ฌด๊ธฐํ™”: ์ˆจ๊ฒจ์ง„ ๋ณ€์ˆ˜๋“ค ๋‹ค๋ฃจ๊ธฐ

โœ… ์˜ํ˜ธ์˜ ์™„๋ฒฝํ•œ ๋ฆฌํŒฉํ† ๋ง: current ๋ฌด๊ธฐ๊ณ  ์‚ฌ์šฉ

  1. UI(ํ™”๋ฉด)์— ๊ทธ๋ฆด ๋‚ด์šฉ์€ -> ๋ Œ๋”๋ง์— ๋ฐ˜์‘ํ•˜๋Š” useState ๋งˆ์ดํฌ์— ๋‹ด๋Š”๋‹ค (seconds)
  2. ๋‚ด๋ถ€ ๋กœ์ง ํ†ต์ œ์šฉ(์•Œ๋žŒ, ํƒ€์ด๋จธ ์•„์ด๋””, ๋“œ๋ž˜๊ทธ ์Šคํฌ๋กค ํ”ฝ์…€ ์ด์ „ ์œ„์น˜ ๋“ฑ) ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฐ์ดํ„ฐ๋Š” -> ๋น„๋ฐ€ ๊ธˆ๊ณ  useRef์— ๋‹ด์•„ ๋ชฐ๋ž˜ ๊ด€๋ฆฌํ•œ๋‹ค (timerRef)
// โœ… ์šฐ์•„ํ•œ ๊ณ ์„ฑ๋Šฅ ๋ Œ๋”๋ง ์ฝ”๋“œ (Pro Approach)
function Stopwatch() {
  const [seconds, setSeconds] = useState(0); // ํ™”๋ฉด UI์™€ ์ง๊ฒฐ๋œ ์œ ์ผํ•œ ์นœ๊ตฌ
  const timerRef = useRef(null); // ๐ŸŽฏ ๋ฆฌ๋ Œ๋”๋ง ๊ฐ์‹œ ๋ฉด์ œ๊ถŒ ๋ฐœ๊ธ‰!
 
  const handleStart = () => {
    if (timerRef.current) return; // ์ด๋ฏธ ๋Œ๊ณ  ์žˆ์œผ๋ฉด ๋ฐฉ์–ด!
 
    // ์ด ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด๋„ ๋ฆฌ์•กํŠธ๋Š” ๋ˆˆ๋„ ๊นœ์ง ์•ˆ ํ•ฉ๋‹ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง 0ํšŒ ๋‹ฌ์„ฑ.
    timerRef.current = setInterval(() => setSeconds(s => s + 1), 1000);
  };
 
  const handleStop = () => {
    clearInterval(timerRef.current);
    timerRef.current = null; // ์ดˆ๊ธฐํ™”
  };
 
  return (
    <div>
      <p>๊ฒฝ๊ณผ ์‹œ๊ฐ„: {seconds}์ดˆ</p>
      <button onClick={handleStart}>์‹œ์ž‘</button>
      <button onClick={handleStop}>๋ฉˆ์ถฐ!</button>
    </div>
  );
}

๊น”๋”ํ•ฉ๋‹ˆ๋‹ค. setTimerId(id)๋กœ ๋ Œ๋”๋ง์„ ํ•œ ๋ฒˆ ๋” ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์–ด์กŒ์–ด.
timerRef.current = ... ํ• ๋‹น๋ฌธ์€ React์—๊ฒŒ ๋ Œ๋”๋ง์„ ์š”์ฒญํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ํƒ€์ด๋จธ ์ œ์–ด ๊ฐ’์ฒ˜๋Ÿผ UI์™€ ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ’ฅ ์—๋Ÿฌ ํ•ด๊ฒฐ ์นดํƒˆ๋กœ๊ทธ

โŒ useRef ๊ธˆ๊ณ  ์•ˆ์˜ ๊ฐ’์„ ํ™”๋ฉด์— ๋…ธ์ถœ์‹œํ‚ค๋Š” ์‚ฌ์ƒ๋ˆ„๊ฐ

์–ธ์ œ ๋‚˜์˜ค๋Š”๊ฐ€?

const countRef = useRef(0);
 
const handleAdd = () => {
  countRef.current += 1;
  // ๐Ÿ’ฅ ์˜์ฒ : "ํžˆํžˆ ๋ˆŒ๋ €๋Š”๋ฐ ํ™”๋ฉด ์ˆซ์ž๊ฐ€ ์•ˆ ๋ฐ”๋€Œ์ž–์•„์š”!"
};
 
// ... <button onClick={handleAdd}>๋‚˜๋น„ ๋ˆ„๋ฆ„ ํšŸ์ˆ˜: {countRef.current}</button> ...

์›์ธ: useRef๊ฐ€ ๋ Œ๋”๋ง์„ ๋ฐœ๋™์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•˜๊ณ  ํ™”๋ฉด UI(JSX ๋ฐ˜ํ™˜ ๊ณต๊ฐ„)์— ๋„ฃ์€ ๊ฑฐ์•ผ. ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ current๋ฅผ ๋ฐ”๊ฟ”๋„ React๋Š” ์ƒํƒœ ๋ณ€๊ฒฝ ์‹ ํ˜ธ๋ฅผ ๋ฐ›์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ™”๋ฉด์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋Š”๋‹ค.
๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ์šฐ์—ฐํžˆ ๋‹ค๋ฅธ ์ƒํƒœ(State)๊ฐ€ setState๋˜์–ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋˜๋ฉด, ref์— ์Œ“์—ฌ ์žˆ๋˜ ๊ฐ’์ด ๊ทธ์ œ์•ผ ํ™”๋ฉด์— ๋ฐ˜์˜๋  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” "๋ฐฉ๊ธˆ ๋ˆ„๋ฅธ ๊ฐ’์ด ์™œ ์ด์ œ ๋‚˜ํƒ€๋‚˜์ง€?"๋ผ๊ณ  ํ˜ผ๋ž€์„ ๊ฒช๋Š”๋‹ค.

ํ•ด๊ฒฐ์ฑ…:
useRef์˜ current ์†์„ฑ๊ฐ’์„ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฌผ(<p>{์—ฌ๊ธฐ}</p>)์˜ ํ•ต์‹ฌ ๋ฐ์ดํ„ฐ๋กœ ์“ฐ์ง€ ๋งˆ์„ธ์š”. UI์™€ ์ง๊ฒฐ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ผ๋ฉด ๋ฐ˜๋“œ์‹œ useState๋ฅผ ๊ณ ๋ฅด์‹ญ์‹œ์˜ค.
"๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์‹œ๊ฐ์ ์ธ ๋ณ€ํ™”๋ฅผ ๋‚ณ๋Š”๊ฐ€?" -> YES๋ฉด State, NO๋ฉด Ref์ž…๋‹ˆ๋‹ค.


๐Ÿ ์ด๋ฒˆ์— ๋ฐฐ์šด ๋‚ด์šฉ ์ด์ •๋ฆฌ

๋„๊ตฌ์˜ ๋ณธ์งˆuseState (๋งˆ์ดํฌ)useRef (๋น„๋ฐ€ ๊ธˆ๊ณ )
๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด?์ฆ‰์‹œ ๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ (UI ์—…๋ฐ์ดํŠธ O)๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ ์•ˆ ํ•จ (ํ™”๋ฉด ์–ผ์–ด์žˆ์Œ X)
๋ Œ๋”๋ง ๊ฐ„ ๋ฐ์ดํ„ฐ ์œ ์ง€O (ํ•˜์ง€๋งŒ ๋ Œ๋”๋ง๋งˆ๋‹ค ๊ฐ’์„ ์Šค๋ƒ…์ƒท ๊ณ ์ • ๋ณต์‚ฌํ•ด ์คŒ)O (์–ธ์ œ ๊ฐ€๋ฆฌ์ผœ๋„ '๋™์ผํ•œ ์ตœ์‹  ์ฃผ์†Œ ํž™ ๋ฒ„ํผ' ์ฐธ์กฐ)
์–ด๋””์— ์–ด์šธ๋ฆฌ๋Š”๊ฐ€?์ธํ’‹ ์ž…๋ ฅ ํ…์ŠคํŠธ, ๋ชจ๋‹ฌ์ฐฝ(T/F), ๋ฒ„ํŠผ ์ปฌ๋Ÿฌ ๋“ฑ ํ™”๋ฉด ๊ทธ๋ฆด ๋•Œํƒ€์ด๋จธ ์•„์ด๋”” ์ฅ๊ธฐ, DOM ์š”์†Œ ํฌ์ปค์Šค ์กฐ์ž‘ํ•˜๊ธฐ, ์ด์ „(Prev) ๊ฐ’ ๋ชฐ๋ž˜ ์ €์žฅํ•˜๊ธฐ ๋“ฑ

๐Ÿ’ก ํ•œ ์ค„๋กœ ๊ธฐ์–ตํ•˜๊ธฐ
"๋‚˜๋งŒ์˜ ์ด ์†Œ์ค‘ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ, ์˜จ ๋งˆ์„์„ ๋’ค์ง‘์–ด์—Ž๊ณ  ํ™”๋ฉด์„ ์ƒˆ๋กœ๊ณ ์นจํ•˜๊ณ  ์‹ถ์€๊ฐ€?" ์ด ๋ฌธํ•ญ์— "์•„๋‹ˆ์š”, ๊ทธ๋ƒฅ ๋ฐ์ดํ„ฐ ์ˆซ์ž๋งŒ ํ˜ผ์ž ๊ธฐ์–ตํ•ด์ฃผ๋ฉด ๋ผ์š”."๋ผ๊ณ  ์™ธ์น˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋ฌด์กฐ๊ฑด ๋ง์„ค์ด์ง€ ๋ง๊ณ  useRef ์•ˆ์ฃผ๋จธ๋‹ˆ๋ฅผ ์งœ๋ผ.

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. useState ๋Œ€์‹  useRef๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์™„๋ฒฝํ•œ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค(Best Practice)๋กœ ๋ถ€ํ•ฉํ•˜๋Š” ์ƒํ™ฉ์„ ํ•˜๋‚˜ ๊ณ ๋ฅด์„ธ์š”.

  • A) ์‚ฌ์šฉ์ž๊ฐ€ ์‡ผํ•‘๋ชฐ ๊ฒ€์ƒ‰์ฐฝ์—์„œ ํƒ€์ดํ•‘ํ•˜๊ณ  ์žˆ๋Š” ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰์–ด ํ…์ŠคํŠธ ๊ฐ’์„ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ.
  • B) ํ˜„์žฌ ๋กœ๊ทธ์ธํ•œ ํ† ํฐ์ด ์œ ํšจํ•œ ์œ ์ €์ธ์ง€์— ๋Œ€ํ•œ boolean(T/F) ๊ฐ’์„ ์ €์žฅํ•˜๊ณ  ๊ถŒํ•œ ์—๋Ÿฌ ๋ชจ๋‹ฌ์„ ๋„์šธ ๋•Œ.
  • C) ์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ์ดํ›„ 30์ดˆ ๋™์•ˆ ์•„๋ฌด ํด๋ฆญ๋„ ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒฝ๊ณ  ํŒ์—…์„ ๋„์›Œ์ค„ setTimeout ํ•จ์ˆ˜์˜ ์˜ˆ์•ฝ ๊ณ ์œ  ํ†ต์ œ ์•„์ด๋””(ID)๋ฅผ ์ €์žฅํ•  ๋•Œ.
  • D) ์‚ฌ์šฉ์ž์˜ ํ˜„์žฌ ์‡ผํ•‘ ์นดํŠธ์— ๋‹ด๊ธด ๋ฌผํ’ˆ ์ด ๊ฒฐ์ œ ๊ธˆ์•ก์„ ์‹ค์‹œ๊ฐ„ ๊ณ„์‚ฐํ•˜์—ฌ ์šฐ์ธก ํ•˜๋‹จ ์˜์ˆ˜์ฆ์— ๋ณด์—ฌ์ค„ ๋•Œ.

โœ… ์ •๋‹ต: C

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: ๋ Œ๋”๋ง ํŠธ๋ฆฌ๊ฑฐ ์—ฌ๋ถ€๋งŒ ๊ตฌ์ƒํ•  ์ค„ ์•Œ๋ฉด ๋ฉ๋‹ˆ๋‹ค! A์˜ ๊ฒ€์ƒ‰์–ด, B์˜ ๋ชจ๋‹ฌ T/F, D์˜ ์นดํŠธ ๊ฒฐ์ œ์•ก ์ˆซ์ž๋Š” ์ „๋ถ€ "๊ฐ’์ด ํ•œ ๋ฒˆ์ด๋ผ๋„ ๋ฐ”๋€Œ๋ฉด ํ™”๋ฉด์˜ ํ”ฝ์…€ UI๊ฐ€ ์œ ์ € ๋ˆˆ์•ž์—์„œ ์ฆ‰์‹œ์ฆ‰์‹œ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•˜๋Š”" UI ์ง๊ฒฐํ˜• ๋ฐ์ดํ„ฐ์ด๋ฏ€๋กœ ๋ฌด์กฐ๊ฑด useState์˜ ์˜์—ญ์ž…๋‹ˆ๋‹ค.
๋ฐ˜๋ฉด C์˜ ํƒ€์ด๋จธ ์•„์ด๋””๋Š” ๋‹จ์ˆœ ์ •์ˆ˜ ์ˆซ์ž(1, 2, 3...)์ผ ๋ฟ ๋ธŒ๋ผ์šฐ์ € DOM ์–ด๋””์—๋„ ์ถœ๋ ฅ๋  ์ผ์ด ์—†์œผ๋ฉฐ, ์˜ค์ง ํด๋ฆฐ์—… ์‹œ clearTimeout(ID) ์ฒ˜๋ฆฌ ๋กœ์ง์„ ํ†ต์ œํ•˜๊ธฐ ๋’ท๊ตฌ๋ฉ ๋ฐ์ดํ„ฐ์ด๋ฏ€๋กœ ๋ฆฌ์•กํŠธ ์—”์ง„์— ์‹œ๋น„(๋ฆฌ๋ Œ๋”๋ง ๋ถ€๋‹ด)๋ฅผ ๊ฑธ ํ•„์š”๊ฐ€ ์ „ํ˜€ ์—†๋Š” useRef์˜ ์ตœ์  ๋ฌด๋Œ€์ž…๋‹ˆ๋‹ค.

Q2. ๋‹ค์Œ ์ค‘ ์˜์ฒ ์ด๊ฐ€ ์ง  useRef ์กฐ์ž‘์— ๋Œ€ํ•ด, ๋ฆฌ์•กํŠธ ํ•ต์‹ฌ ํŒ€ ๋™๋ฃŒ๊ฐ€ ๊ฐ€์žฅ ๊ฒฝ์•…(Horrify)ํ•˜๊ณ  ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์‹œ ๋ฐ”๋กœ ๋ฐ˜๋ ค๋ฅผ ๋จน์ผ ์น˜๋ช…์  ํŒจํ„ด์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • A) <input ref={myInputRef} /> ํ˜•ํƒœ๋กœ DOM ์š”์†Œ์— ์ง์ ‘ ๊ฐˆ๊ณ ๋ฆฌ๋ฅผ ๋˜์ง„ ๊ฒƒ.
  • B) useEffect ์™ธ๋ถ€ ํด๋ฆฐ์—… ๊ณต๊ฐ„์—์„œ myRef.current = null๋กœ ์ดˆ๊ธฐํ™”ํ•œ ๊ฒƒ.
  • C) <div>๋‚ด ๋น„๋ฐ€ ๊ธˆ๊ณ : {secretRef.current}</div> ํ˜•ํƒœ๋กœ JSX ๋ Œ๋”๋ง ๋ฐ˜ํ™˜ ๊ณต๊ฐ„์•ˆ์— ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์–ด๋‘” ๊ฒƒ.
  • D) ์™ธ๋ถ€ ํ™˜๊ฒฝ์— const initial = 'abc'๋ฅผ ๋นผ๋‘๊ณ  useRef(initial)๋กœ ๊ฐ’์„ ์ดˆ๊ธฐ ์„ธํŒ…ํ•œ ๊ฒƒ.

โœ… ์ •๋‹ต: C

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค: ์•ˆํ‹ฐํŒจํ„ด์ž…๋‹ˆ๋‹ค. useRef๋Š” ๊ฐ’์„ ์ €์žฅํ•˜์ง€๋งŒ ๋ณ€๊ฒฝ ์‚ฌ์‹ค์„ React ๋ Œ๋”๋Ÿฌ์— ์•Œ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ secretRef.current๋ฅผ JSX์— ์ง์ ‘ ๋ณด์—ฌ์ฃผ๋ฉด ๊ฐ’์€ ๋ฐ”๋€Œ์—ˆ๋Š”๋ฐ ํ™”๋ฉด์€ ๊ฐฑ์‹ ๋˜์ง€ ์•Š๋Š” ์ƒํƒœ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ๊ฐ’์€ useState, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋‚˜ Effect์—์„œ๋งŒ ํ•„์š”ํ•œ ๊ฐ’์€ useRef๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. (A๋Š” ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•, B์™€ D๋Š” ์ •์ƒ ์‚ฌ์šฉ๋ฒ•).

Q3. ์ฃผ๊ด€์‹ ๋…ผ์ˆ : useRef๊ฐ€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ํšŸ์ˆ˜(์žฌ์‹คํ–‰)์— ๊ด€๊ณ„์—†์ด ์–ด๋–ป๊ฒŒ ํ•ญ์ƒ "๋‹จ ํ•˜๋‚˜์˜ ์˜จ์ „ํ•œ ํ†ต(๋ฐ•์Šค)"์„ ๊ธฐ์–ตํ•˜๊ณ  ์˜๊ตฌ ๋ถˆ๋ณ€ํ•˜๊ฒŒ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋ฆฌ์•กํŠธ ๋‚ด๋ถ€์—์„œ ํ‰๋‚ด(๊ตฌํ˜„) ๋‚ด์—ˆ์„์ง€, useState ๊ฐœ๋…์„ ๋น—๋Œ€์–ด ๊ทธ ๋น„๋ฐ€์˜ ์ž‘๋™ ์›๋ฆฌ๋ฅผ ์„œ์ˆ ํ•˜์‹œ์˜ค.

โœ… ์ •๋‹ต ๋ฐ ์ฃผ๊ด€์‹ ํ•ด์„ค:

๋‚ด๋ถ€ ์ž‘๋™ ์›๋ฆฌ: ๊ณต์‹ ๋ฌธ์„œ ๊ธฐ์ค€์œผ๋กœ useRef(initialValue)๋Š” current ์†์„ฑ์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋‹ค์Œ ๋ Œ๋”์—์„œ๋„ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. initialValue๋Š” ์ฒซ ๋ Œ๋” ์ดํ›„์—๋Š” ๋‹ค์‹œ ์“ฐ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ์€ "๊ฐ™์€ ref ๊ฐ์ฒด์˜ current๋งŒ ๋ฐ”๋€Œ๊ณ , React ์ƒํƒœ ํ์—๋Š” ์•„๋ฌด ์—…๋ฐ์ดํŠธ๋„ ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค" ๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ’์€ ๋ Œ๋” ์‚ฌ์ด์— ์œ ์ง€๋˜์ง€๋งŒ, ๊ฐ’ ๋ณ€๊ฒฝ๋งŒ์œผ๋กœ ํ™”๋ฉด์€ ๋‹ค์‹œ ๊ทธ๋ ค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ํŠน์„ฑ ๋•๋ถ„์— ํƒ€์ด๋จธ ID์ฒ˜๋Ÿผ ํ™”๋ฉด๊ณผ ๋ฌด๊ด€ํ•œ ๊ฐ’์€ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๊ณ , ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ ๊ฐ’์€ state๋กœ ๋ถ„๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

ํ™”๋ฉด์— ๊ทธ๋ฆฌ์ง€๋„ ์•Š์„ ํƒ€์ด๋จธ ์•„์ด๋””๋กœ ๋ฌด์˜๋ฏธํ•œ ๋ Œ๋”๋ง์„ ๋งŒ๋“ค๊ณ  ์žˆ์—ˆ๋‹ค๋‹ˆ, useRef๊ฐ€ ๋‹จ์ˆœํžˆ ํฌ์ปค์Šค ์žก๋Š” ์šฉ๋„๊ฐ€ ์•„๋‹ˆ๋ผ '์•ˆ์ฃผ๋จธ๋‹ˆ ๋น„๋ฐ€ ๊ธˆ๊ณ '๋ผ๋Š” ๋น„์œ ๊ฐ€ ํ•ต์‹ฌ์„ ๊ด€ํ†ตํ–ˆ๋‹ค.

๐Ÿ’ก "์ƒํƒœ(State)๋Š” ๋งˆ์ดํฌ, ์ฐธ์กฐ(Ref)๋Š” ๋น„๋ฐ€ ๊ธˆ๊ณ . ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€ํ•  ๋•Œ ํ™”๋ฉด ํ”ฝ์…€์ด ๋ฐ”๋€Œ์–ด์•ผ ํ•˜๋Š”์ง€ ํ•œ ๋ฒˆ๋งŒ ์ƒ๊ฐํ•ด๋ณด์ž!"

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ณ€์ˆ˜๋ž‘ ๋‹ค๋ฅผ ๊ฒŒ ์—†์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ ์ˆ˜๋ช… ๋‚ด๋‚ด ์˜๊ตฌ ๋ณด์กด๋œ๋‹ค๋Š” ๊ฒŒ ์‹ ๊ธฐ์›์ด๋‹ค. ๋‹น์žฅ ๋‚ด์ผ ์ถœ๊ทผํ•ด์„œ ์“ธ๋ฐ์—†์ด ์ƒํƒœ๋กœ ๋นผ๋†“์€ ์Šคํฌ๋กค ์œ„์น˜๊ฐ’์ด๋‚˜ ํƒ€์ด๋จธ ์‹๋ณ„์ž๋“ค ๋‹ค useRef๋กœ ๊ฐˆ์•„์—Ž์–ด์•ผ์ง€. ์†์ด ๋ปฅ ๋šซ๋ฆฌ๋Š” ๊ธฐ๋ถ„์ด๋‹ค.