[React] useRef 사용법 익히기 with some examples

studying  · 3 mins read

들어가며

useRef hook에 대해 간단하게 정리.
javacript에서는 getElementById와 같은 DOM Selector 함수를 사용해서 특정 DOM을 선택한다.
리액트에서는 특정 DOM을 선택할 때 ref를 사용하는데 함수형 컴포넌트에서 ref를 사용해서 특정 DOM을 선택하는 과정을 살펴보자.

사용 예시

함수형 컴포넌트에서는 useRef 라는 hook을 사용해서 DOM을 선택하게 된다.
어떻게 useRef를 사용하는지 다음 코드를 살펴보자.

import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const useClick = (onClick) => {
  if (typeof onClick !== "function") {
    return;
  }
  const element = useRef();
  useEffect(() => {
    // App component가 처음 렌더링된 후에(즉, App component의 return부분에서 element 객체의 current 값이 설정됨)
    // useEffect의 callback함수가 실행됨.
    if (element.current) {
      // 선택된 DOM에 eventListener를 추가
      element.current.addEventListener("click", onClick);
    }
    // cleanup 함수를 return
    return () => {
      // 컴포넌트가 사라질 때 선택된 DOM에 eventListener를 제거
      if (element.current) {
        element.current.removeEventListener("click", onClick);
      }
    };
  }, []);
  return element;
};

const App = () => {
  const sayHello = () => console.log("say hello");
  // useClick 함수를 호출하면 useRef 객체를 return받게 됨(DOM 선택은 아직 안 일어남 즉, title.current의 값은 undefined!)
  const title = useClick(sayHello);
  return (
    <div className="App">
      {/*DOM 선택!(title.current값이 해당 DOM으로 설정됨)*/}
      <h1 ref={title}>Hi</h1>
    </div>
  );
};

useRef hook의 다른 기능

특정 DOM을 선택할 때 말고도 useRef hook을 사용하는 경우가 있다.
컴포넌트 안에서 useRef를 사용해서 변수를 관리할 수 있는데 useRef를 사용해서 변수를 관리하게 되면 해당 변수는 컴포넌트가 리렌더링 되어도 변수의 값이 초기화 되지 않고, 변수의 값이 바뀌어도 컴포넌트가 리렌더링 되지 않는다.
useRef는 일반적인 자바스크립트 객체이기 때문에 useRef로 관리되는 변수를 참조할 때마다 같은 메모리 주소를 가지게 되고 === 연산이 항상 true를 반환하게 돼서 해당 변수의 값이 바뀌어도(객체 자체가 새로 정의되는 것이 아니라 객체의 current property에 해당하는 value가 바뀜) 리렌더링이 되지 않는다.
하지만 함수 컴포넌트 내부에 변수를 선언한다면, 렌더링 될 때마다 값이 초기화 됩니다. (우리는 초기화 되는 것을 원하지 않음, 바뀐 변수의 값을 사용하고 싶음)

또한 리액트 컴포넌트에서의 상태는 상태를 update해주는 함수를 호출하고 나서 그 다음 렌더링 이후로 update 된 상태를 조회 할 수 있는 반면, useRef 로 관리하고 있는 변수는 설정 후 바로 조회 할 수 있다.

사용 예시

// nextId 객체의 current value값을 1로 초기화
const nextId = useRef(1);
// nextId가 만들어지고 어떤 함수 안에서 아래의 코드가 1번 실행된다고 하자.
nextId.current += 1;

위의 코드를 포함하는 컴포넌트가 리렌더링이 되어도 nextId.current값은 update된 값(2)으로 유지된다. 따라서 컴포넌트의 리렌더링 유무에 관계 없이 해당 변수의 값을 update시키거나 update 된 값을 update 되자마자 바로 조회 할 수 있게 된다.

references

“벨로퍼트와 함께하는 모던 리액트”, 2021년 03월 09일 접속, https://react.vlpt.us/basic/12-variable-with-useRef.html devlog”, 2021년 03월 17일 접속, rinae.dev/posts/a-complete-guide-to-useeffect-ko#%EA%B7%B8%EB%9F%AC%EB%A9%B4-%ED%81%B4%EB%A6%B0%EC%97%85cleanup%EC%9D%80-%EB%AD%90%EC%A7%80>