레퍼런스

useRef(initialValue)

컴포넌트의 최상위 레벨에서 useRef를 호출하여 를 선언합니다.

매개변수

  • initialValue: ref 객체의 current프로퍼티 초기 설정값입니다. 여기에는 어떤 유형의 값이든 지정할 수 있습니다. 이 인자는 초기 렌더링 이후부터는 무시됩니다.

반환값

useRef는 단일 프로퍼티를 가진 객체를 반환합니다:

  • current: 처음에는 전달한 initialValue로 설정됩니다. 나중에 다른 값으로 바꿀 수 있습니다. ref 객체를 JSX 노드의 ref어트리뷰트로 React에 전달하면 React는 current프로퍼티를 설정합니다.

다음 렌더링에서 useRef는 동일한 객체를 반환합니다.

주의 사항

  • ref.current 프로퍼티는 state와 달리 변이할 수 있습니다. 그러나 렌더링에 사용되는 객체(예: state의 일부)를 포함하는 경우 해당 객체를 변이해서는 안 됩니다.
  • ref.current 프로퍼티를 변경해도 React는 컴포넌트를 다시 렌더링하지 않습니다. ref는 일반 JavaScript 객체이기 때문에 React는 사용자가 언제 변경했는지 알지 못합니다.
  • 를 제외하고는 렌더링 중에 ref.current를 쓰거나 읽지 마세요. 이렇게 하면 컴포넌트의 동작을 예측할 수 없게 됩니다.
  • Strict Mode에서 React는 컴포넌트 함수를 두 번 호출하여 이는 개발 환경 전용 동작이며 Production 환경에는 영향을 미치지 않습니다. 각 ref 객체는 두 번 생성되고 그중 하나는 버려집니다. 컴포넌트 함수가 순수하다면(그래야만 합니다), 컴포넌트의 로직에 영향을 미치지 않습니다.

사용법

ref로 값 참조하기

컴포넌트의 최상위 레벨에서 useRef를 호출하여 하나 이상의 를 선언합니다.

useRef는 처음에 제공한 초기값으로 설정된 단일 current 프로퍼티가 있는 ref 객체를 반환합니다.

다음 렌더링에서 useRef는 동일한 객체를 반환합니다. 정보를 저장하고 나중에 읽을 수 있도록 current 속성을 변경할 수 있습니다. 가 떠오를 수 있지만, 둘 사이에는 중요한 차이점이 있습니다.

ref를 변경해도 리렌더링을 촉발하지 않습니다. 즉 ref는 컴포넌트의 시각적 출력에 영향을 미치지 않는 정보를 저장하는 데 적합합니다. 예를 들어 를 저장했다가 나중에 불러와야 하는 경우 ref에 넣을 수 있습니다. ref 내부의 값을 업데이트하려면 current 프로퍼티를 수동으로 변경해야 합니다:

나중에 ref에서 해당 interval ID를 읽어 할 수 있습니다:

ref를 사용하면 다음을 보장합니다:

  • (렌더링할 때마다 재설정되는 일반 변수와 달리) 리렌더링 사이에 정보를 저장할 수 있습니다.
  • (리렌더링을 촉발하는 state 변수와 달리) 변경해도 리렌더링을 촉발하지 않습니다.
  • (정보가 공유되는 외부 변수와 달리) 각각의 컴포넌트에 로컬로 저장됩니다.

ref를 변경해도 다시 렌더링되지 않으므로 화면에 표시되는 정보를 저장하는 데는 ref가 적합하지 않습니다. 대신 state를 사용하세요. 더 자세한 내용은 에서 확인하세요.


ref로 DOM 조작하기

ref를 사용하여 을 조작하는 것은 특히 일반적입니다. React에는 이를 위한 기본 지원이 있습니다.

먼저 초기값nullref 객체를 선언하세요:

그런 다음 ref 객체를 ref 속성으로 조작하려는 DOM 노드의 JSX에 전달하세요:

React가 DOM 노드를 생성하고 화면에 그린 후, React는 ref 객체의 current프로퍼티를 DOM 노드로 설정합니다. 이제 DOM 노드 <input> 접근해 와 같은 메서드를 호출할 수 있습니다.

노드가 화면에서 제거되면 React는 current 프로퍼티를 다시 null로 설정합니다.

자세한 내용은 에서 알아보세요.


ref 콘텐츠 재생성 피하기

React는 초기에 ref 값을 한 번 저장하고, 다음 렌더링부터는 이를 무시합니다.

new VideoPlayer()의 결과는 초기 렌더링에만 사용되지만, 호출 자체는 이후의 모든 렌더링에서도 여전히 계속 이뤄집니다. 이는 값비싼 객체를 생성하는 경우 낭비일 수 있습니다.

이 문제를 해결하려면 대신 다음과 같이 ref를 초기화할 수 있습니다:

일반적으로 렌더링 중에 ref.current를 쓰거나 읽는 것은 허용되지 않습니다. 하지만 이 경우에는 결과가 항상 동일하고 초기화 중에만 조건이 실행되므로 충분히 예측할 수 있으므로 괜찮습니다.

자세히 살펴보기

useRef를 초기화할 때 null 검사를 피하는 방법

타입 검사기를 사용하면서 항상 null을 검사하고 싶지 않다면 다음과 같은 패턴을 대신 사용해 볼 수 있습니다:

여기서 playerRef 자체는 nullable합니다. 하지만 타입 검사기에 getPlayer()null을 반환하는 경우가 없다는 것을 확신시킬 수 있어야 합니다. 그런 다음 이벤트 핸들러에서 getPlayer()를 사용하십시오.


문제 해결

커스텀 컴포넌트에 대한 ref를 얻을 수 없습니다

컴포넌트에 ref를 전달하고자 다음과 같이 하면:

다음과 같은 오류가 발생할 것입니다:

Console
TypeError: Cannot read properties of null

기본적으로 컴포넌트는 내부의 DOM 노드에 대한 ref를 외부로 노출하지 않습니다.

이 문제를 해결하려면 ref를 가져오고자 하는 컴포넌트를 찾으세요:

그리고 ref를 컴포넌트가 받는 props 목록에 추가한 뒤, 아래처럼 해당 자식 에 prop으로 ref를 전달하세요.

그러면 부모 컴포넌트가 ref를 가져올 수 있습니다.

자세한 내용은 에서 확인하세요.