ReactJS

React - ( React Hooks 3 - useRef )

jjangsh 2024. 9. 5. 21:33

01. useRef란?

 

(1) useRef hook 소개

useState와 더불어 특정 값을 저장하기 위해 사용하는 대표적인 hook이라고 할 수 있어요. Re-rendering과 상관없이 값을 기억하기 위해 사용되는 것이 본질적 특징이죠. 이 특징을 이용해 자바스크립트 DOM API를 직접 사용하지 않고 DOM 요소를 다루기 위한 용도로도 자주 사용된답니다.

 

(2) 사용방법

import "./App.css";
import { useRef } from "react";

function App() {
  const ref = useRef("초기값");
  console.log("ref", ref);

  return (
    <div>
      <p>useRef에 대한 이야기에요.</p>
    </div>
  );
}

export default App;

콘솔을 확인해보면, ref에는 값이 이렇게 담겨있어요.

 

변경도 가능해요.

import "./App.css";
import { useRef } from "react";

function App() {
  const ref = useRef("초기값");
  console.log("ref 1", ref);

  ref.current = "바꾼 값";
  console.log("ref 1", ref);

  return (
    <div>
      <p>useRef에 대한 이야기에요.</p>
    </div>
  );
}

export default App;

 

 

 

📌이렇게 설정된 ref 값은 컴포넌트가 계속해서 렌더링 되어도 unmount 전까지 값을 유지합니다.

 

이러한 특징 때문에 useRef는 다음 2가지 용도로 사용됩니다.

 

  • (1) 저장공간
    1. state와 비슷한 역할을 해요. 다만 state는 변화가 일어나면 다시 렌더링이 일어나요. 내부 변수들은 초기화가 되죠.
    2. ref에 저장한 값은 렌더링을 일으키지 않아요. 즉, ref의 값 변화가 일어나도 렌더링으로 인해 내부 변수들이 초기화되는 것을 막을 수 있죠.
    3. 컴포넌트가 100번 렌더링 → ref에 저장한 값은 유지돼요.
    4.  정리
      1. state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰면 된다.
      2. ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용한다.

 

  • (2) DOM
    1. 렌더링 되자마자 특정 input이 focusing 돼야 하는 등, DOM 요소를 핸들링해야 하는 순간이라면 useRef를 사용하는 것이 좋은 선택지가 될 수 있습니다. 예시는 아래에서 다뤄요!

 

 

02. 예제 코드로 특징 살펴보기

 

(1) state와 ref의 차이점

plusStateCountButtonHandler와, plusRefCountButtonHandler는 다르게 동작하는게 이해하기

state는 변경되면 렌더링이 되고, ref는 변경되면 렌더링이 안됨.

import "./App.css";
import { useRef, useState } from "react";

function App() {
  const [count, setCount] = useState(0);
  const countRef = useRef(0);

  const plusStateCountButtonHandler = () => {
    setCount(count + 1);
  };

  const plusRefCountButtonHandler = () => {
    countRef.current++;
  };

  return (
    <>
      <div>
        state 영역입니다. {count} <br />
        <button onClick={plusStateCountButtonHandler}>state 증가</button>
      </div>
      <div>
        ref 영역입니다. {countRef.current} <br />
        <button onClick={plusRefCountButtonHandler}>ref 증가</button>
      </div>
    </>
  );
}

export default App;

 

근데, 내부 변수는 그냥 let 키워드로 선언해서 변수 사용하면 안 될까?

let 키워드를 사용하게 되면 렌더링 시 다시 변수가 초기화된답니다. 함수라서 그래요.

리렌더링이 된다 = 함수가 다시 호출된다 = 내부 변수가 다시 쫙 초기화된다.

 

(2) DOM 접근

<input /> 태그에는 ref라는 속성이 있습니다. 이걸 통해 우리는 해당 DOM 요소로 접근할 수 있어요.

 

사용할 화면 만들어주기

import "./App.css";

function App() {
  return (
    <>
      <div>
        아이디 : <input type="text" />
      </div>
      <div>
        비밀번호 : <input type="password" />
      </div>
    </>
  );
}

export default App;

 

 

화면이 렌더링 되고 나면 아이디에 자동 포커싱 되게 할 순 없을까?

 

useRef 사용하여 포커싱 주기

import { useEffect, useRef } from "react";
import "./App.css";

function App() {
  const idRef = useRef("");

  // 렌더링이 될 때
  useEffect(() => {
    idRef.current.focus();
  }, []);

  return (
    <>
      <div>
        아이디 : <input type="text" ref={idRef} />
      </div>
      <div>
        비밀번호 : <input type="password" />
      </div>
    </>
  );
}

export default App;

 

화면이 렌더링 되자마자 바로 focus가 들어갑니다.