React Hooks - useRef

박지현·2023년 2월 13일

React 숙련

목록 보기
4/9
post-thumbnail

2023.02.10

1. useRef란?

(1) useRef hook 소개

DOM 요소에 접근할 수 있도록 하는 React Hook 이다. HTML과 javascript를 사용했을 때 우리는 특정 DOM을 선택하기 위해서 다음과 같이 했었다.

// (1) getElementById 이용
const divTag = document.getElementById('#myDiv');

// (2) querySelector 이용
const divTag2 = document.querySelector('#myDiv');

리액트에서도 DOM을 선택해야 할 상황(화면이 렌더링 되자마자 특정 input 태그가 focusing이 돼야 하는 경우 등)이 생기는데, 그럴때 사용하는것이 useRef hook 이다.

(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. 저장공간
    a. state와 비슷한 역할을 한다. 다만 state는 변화가 일어나면 다시 렌더링이 일어난다. 내부 변수들은 초기화 된다.
    b. ref에 저장한 값은 렌더링을 일으키지 않는다. 즉, ref의 값 변화가 일어나도 렌더링으로 인해 내부 변수들이 초기화 되는 것을 막을 수 있다.
    c. 컴포넌트가 100번 렌더링 → ref에 저장한 값은 유지된다.
    d. 정리하면
    1. state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰면 된다.
    2. ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용한다.
  2. DOM
    설렌더링 되자마자 특정 input이 focusing 돼야 한다면 useRef를 사용하면 된다.

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

(1) state와 ref의 차이점

plusStateCountButtonHandler와, plusRefCountButtonHandler는 다르게 동작한다는걸 알아보자.

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;

(2) DOM 접근

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

#1. 사용할 화면 만들어주기

import "./App.css";

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

export default App;

#2. useRef 사용하여 포커싱 주기

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

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

  const [id, setId] = useState("");

  const onIdChangeHandler = (event) => {
    setId(event.target.value);
  };

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

  // 아이디가 10자리 이상 입력되면 자동으로 비밀번호 필드로 이동하는 useEffect 활용
  useEffect(() => {
    if (id.length >= 10) {
      pwRef.current.focus();
    }
  }, [id]);  // 배치 업데이트를 활용한다

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

export default App;
profile
프론트엔드가 목표!

0개의 댓글