๐ŸŽ‹useRef ํ›… : ํšจ์œจ์ ์ธ ์ปดํฌ๋„ŒํŠธ ๊ด€๋ฆฌ

hyeryeonยท2024๋…„ 8์›” 13์ผ

React

๋ชฉ๋ก ๋ณด๊ธฐ
3/19

๐ŸŽ‹useRef ๊ธฐ์ดˆ

useState vs useRef

  • useState

    ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ƒํƒœ๊ฐ€ ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.
  • useRef

    ์ด์ „ ๊ฐ’๊ณผ ์ƒˆ๋กœ์šด ๊ฐ’์„ ์—ฐ๊ฒฐํ•˜๊ณ , ๋ Œ๋”๋ง๊ณผ๋Š” ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ฐ’์ด ์œ ์ง€๋˜์–ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋ง ์—†์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ์ฃผ๋กœ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๊ฐ’์ด๋‚˜, ๋ฆฌ๋ Œ๋”๋ง์„ ์œ ๋ฐœํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ useState์™€ useRef๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์šฉ๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ์„ ํƒ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
useRef๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง๊ณผ ๊ด€๋ จ์ด ์—†๋Š” ๊ฐ’๋“ค์„ ์ €์žฅํ•  ๋•Œ
  • DOM ์š”์†Œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•  ๋•Œ
  • ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ๊ฒฝ์šฐ

์˜ˆ์ œ : ํฌ์ปค์Šค ๊ด€๋ฆฌ

  • ํฌ์ปค์Šค๋ฅผ ์ž๋™์œผ๋กœ ์„ค์ •ํ•˜๋ ค๋Š” ์ž…๋ ฅ ํ•„๋“œ์— useRef๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
function AutoFocusInput() {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}

useEffect์™€ useRef๋ฅผ ์กฐํ•ฉํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ์ž๋™์œผ๋กœ ์ž…๋ ฅ ํ•„๋“œ์— ํฌ์ปค์Šค๋ฅผ ์ค๋‹ˆ๋‹ค

๐Ÿš ์ ์šฉํ•œ ๊ธฐ์กด์ฝ”๋“œ

// ๊ธฐ์กด useState ์‚ฌ์šฉ ์ฝ”๋“œ
import { useState } from "react";

export default function Player() {
  // enteredPlayerName ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•œ useState ํ›…
  const [enteredPlayerName, setEnteredPlayerName] = useState('');
  const [submitted, setSubmitted] = useState(false);

  // ์ž…๋ ฅ ํ•„๋“œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜
  function handleChange(event){
      setSubmitted(false);
      // ์ž…๋ ฅ ํ•„๋“œ์—์„œ ์ž…๋ ฅ๋œ ๊ฐ’์„ ์ƒํƒœ๋กœ ์„ค์ •
      setEnteredPlayerName(event.target.value);
  }

  function handleClick(){
      setSubmitted(true);
  }
  
  return (
    <section id="player">
      <h2>Welcome {submitted ? enteredPlayerName : "unknown entity"}</h2>
      <p>
        <input
          type="text"
          onChange={handleChange} // ์ž…๋ ฅ ํ•„๋“œ์— ๊ฐ’์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค handleChange ํ•จ์ˆ˜ ํ˜ธ์ถœ
          value={enteredPlayerName} // ์ž…๋ ฅ ํ•„๋“œ ๊ฐ’์€ enteredPlayerName ์ƒํƒœ์™€ ๋™๊ธฐํ™”
        />
        <button onClick={handleClick}>Set Name</button> 
      </p>
    </section>
  );
}

์ž…๋ ฅ ํ•„๋“œ์—์„œ์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ useState๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ž…๋ ฅ์ด ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค handleChange ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ , ์ด ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, submitted ์ƒํƒœ๊ฐ€ true๋กœ ์„ค์ •๋˜์–ด, ์ž…๋ ฅ๋œ ์ด๋ฆ„์ด ํ™”๋ฉด์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
์ด ๋ฐฉ๋ฒ•์€ ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ˜์‘์„ ์ง์ ‘์ ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

๐Ÿš ์ˆ˜์ •๋œ ์ฝ”๋“œ

// useRef๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ
import { useState, useRef } from "react";

export default function Player() {
  // input ์š”์†Œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑ
  const playerName = useRef();

  const [enteredPlayerName, setEnteredPlayerName] = useState('');

  function handleClick(){
    // โญ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ ํ•„๋“œ์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์™€ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
    setEnteredPlayerName(playerName.current.value);
  }
  
  return (
    <section id="player">
      <h2>Welcome {enteredPlayerName || "unknown entity"}</h2> 
      <p>
        <input
          ref={playerName} // โญuseRef ํ›…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ฐธ์กฐ๋ฅผ input ์š”์†Œ์— ํ• ๋‹น
          type="text"
        />
        <button onClick={handleClick}>Set Name</button> 
      </p>
    </section>
  );
}

useRef๋Š” DOM ์š”์†Œ์— ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ฐธ์กฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
์ž…๋ ฅ ํ•„๋“œ์— ์ž…๋ ฅ๋œ ๊ฐ’์€ ์ƒํƒœ๋กœ ๊ด€๋ฆฌ๋˜์ง€ ์•Š๊ณ , ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
handleClick ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งŒ ์ž…๋ ฅ ํ•„๋“œ์˜ ๊ฐ’์„ ์ฝ์–ด ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ฏ€๋กœ,
โญ์ž…๋ ฅ ์ค‘์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฆฌ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์ด ๋‚ด๋ถ€ ์ƒํƒœ์— ์ €์žฅ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


https://hanghae99.spartacodingclub.kr/blog/react-usestate-%EB%8C%80%EC%8B%A0-useref%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EA%B2%BD%EC%9A%B0-20844

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