관리 메뉴

꿈꾸는 개발자

React useRef 사용법 본문

React.js

React useRef 사용법

rickysin 2023. 5. 6. 15:12

의의

useRef는 react의 상태 변환에 따른 rendering 중에 지속적으로 참조할 수 있도록 해주는 Hook이다. 즉 useRef는 렌더링의 영향을 받지 않는다고 볼 수 있다. 일단 무슨 말인가 싶을 거지만 밑에 추가적인 설명을 보면 이해를 할 수 있을 것이다.


사용법

import { useRef } from 'react';

function MyComponent() {
  const intervalRef = useRef(0);
  const inputRef = useRef(null);
  // ...

공식문서에 따르면 위처럼 가장 최상단에 useRef를 선언해줄 것을 권장하고 있다. 

 

Parameters

 

  • 초깃값(initialValue): Object current 프로퍼티가 담고 있었으면 하는 초기값을 지정해주는 것이다. (어떠한 타입이든 상관이 없다)

useRef의 값을 출력해보면 위와 같이 Object의 current값이 담겨져 있는 것을 확인할 수 있다.

 

Returns

 

위에 언급했듯이 useRef를 console.log해보면 위처럼 Object가 나온다(즉 저것을 반환한다는 의미). property는 보이다 시피 current 하나 밖에 없다. current의 경우 초기에 useRef(초깃값)에서 초깃값을 담게 되고, 만약 jsx node 컴포넌트의 attributes로 ref를 설정해주고 값을 지정해주면 해당 node element가 current에 들어가게 된다. 


참고사항

  • ref.current의 값은 변경이 가능하지만, 만약 해당 값이 객체 형태로 state를 담고 있다면 변경을 지양해야 한다.
  • ref.current의 경우 값이 변경되더라도 react는 state와 달리 해당 변환를 인지하지 못한다(ref의 경우 순수 JS Object이기 때문)
  • 따라서, re-rendering 과정에서 ref를 읽거나 쓰는 것은 예상치 못한 결과를 초래할 수도 있다. 
  • strictMode에선 react는 우발적인 실수?우?를 발견하도록 하기 위해 react-component를 두 번씩 호출하게 된다. 만약 컴포넌트가 순수함수이면 문제가 되지 않지만, 아닐 경우 문제가 될 수도 있음(useRef의 값이 두 번 생성 된 후 하나는 패기되는 형태이기 때문에)

사용하는 경우

1. Ref를 사용한 값의 저장

Ref의 current property에 useState처럼 값을 저장하는 목적으로 사용할 수 있다. 하지만 ref와 state의 근본적인 차이점은 state의 경우 값이 변경되면 re-rendering이 발생하는 반면, ref의 경우 전혀 그렇지 않다는 것이다. 따라서, 공식문서에 따르면 외부로 즉 사용자 화면에 표출되지 않는 내부 값을 저장하는 데 유용하게 사용할 수 있다고 한다. (Ref vs State에 대한 보다 자세한 비교와 추가적인 설명은 해당 링크에서 확인할 수 있다)

 

공식문서 예시 코드: 

import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}

위 코드에서 count 값을 저장하는 데 ref.current 사용할 수 있는 것은 해당 값이 오직 handle 안에서만 참조되기 때문이다. 만약 위와 같은 방법이 아닌, JSX 내에 {ref.current} 이런식으로 사용을 했다면, btn을 클릭했다고 해서 값이 올라가지는 않을 것이다(re-rendering이 발생하지 않기 때문에)

 

공식문에서 따르면 ref를 rendering 과정에서 호출하지 않는 것이 중요하다고 한다(순수 함수처럼 순수 컴포넌트를 유지해야 하기 때문에)

function MyComponent() {
  // ...
  // 🚩 Don't write a ref during rendering
  myRef.current = 123;
  // ...
  // 🚩 Don't read a ref during rendering
  return <h1>{myOtherRef.current}</h1>;
}

대신에 아래와 같이 useEffect/Handle함수 내에서 사용하기를 권장하고 있다. 

function MyComponent() {
  // ...
  useEffect(() => {
    // ✅ You can read or write refs in effects
    myRef.current = 123;
  });
  // ...
  function handleClick() {
    // ✅ You can read or write refs in event handlers
    doSomething(myOtherRef.current);
  }
  // ...
}

그 외에도 DOM 조작을 하기 위해 ref를 사용하는 경우도 있고(이건 많은 예시와 자료들이 있어서 생략 예정, 궁금하시면 공식문에서 찾아보시길....(보통 input에 ref.current.focus() 예시가 많이 나옵니다)

 

추가적으로 react component에선 ref를 사용할 수 없다. react component에서 ref를 사용하기 위해선 "forwardRef" 사용해야 하는데 관련 사용 예시와 설명은 아래 링크(개인 프로젝트 정리 블로그)에 나와 있으니 궁금하시면 참고하시길 

 

https://velog.io/@rickyshu/React-%EB%AC%B4%ED%95%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

 

React-[무한 스크롤 구현하기]

전체 코드: 깃헙 링크 무한 스크롤의 필요성 한 페이지에서 대량의 데이터를 보여줄 수 있다는 장점이 있다(페이지네이션과 대치되지만, 요즘은 무한 스크롤을 사용하는 곳들이 많이 보인다) 사

velog.io

 

 


참고 자료

https://react.dev/reference/react/useRef#referencing-a-value-with-a-ref

 

useRef – React

The library for web and native user interfaces

react.dev