useRef는 리액트 훅으로서 렌더링 없이 값을 참고할 수 있게 해준다.
const ref = useRef(initialValue)
import { useRef } from 'react';
function MyComponent() {
const intervalRef = useRef(0);
const inputRef = useRef(null);
// ...
Parameters
initialValue: ref 객체의 current 속성에 처음 설정하고 싶은 값으로 어떤 타입이든 사용할 수 있으며 초기 렌더 이후에는 무시된다.
Returns
useRef는 current라는 속성을 가진 객체를 반환
current 초기값 initialValue로 설정되며 이후 이 값은 자유롭게 바꿀 수 있음
ref 객체를 JSX 노드에 ref 속성으로 전달하면 React가 해당 DOM 요소에 대한 참조를 current에 설정
→ 이후의 렌더링에서도 useRef는 항상 동일한 객체를 반환
Caveats
중요한 주의사항도 읽어보자

ref.current 속성은 변영 가능하나 만약 ref.current안에 렌더링 결과에 영향을 주는 값(Ex,상태 관련)을 넣었다면 그 값은 직접 바꾸면 안된다.
너가 ref.current 속성을 변경했다면 React는 해당 컴포넌트에 리렌더링을 일으키지 않는다.
ref는 일반 JavaScript 객체이기 때문에 React는 언제 변경되는지 인식하지 못한다.
초기화를 제외하고 렌더링 중에는 ref.current쓰거나 읽지 말 것
→ 컴포넌트의 동작이 예측 불가능해짐
// 읽기 & 쓰기 , write and read
function MyComponent() {
// ...
// 🚩 Don't write a ref during rendering
myRef.current = 123;
// ...
// 🚩 Don't read a ref during rendering
return <h1>{myOtherRef.current}</h1>;
}
다음 렌더링에서도 useRef는 항상 같은 객체를 반환한다.
current 속성의 값을 변경해서 정보를 저장하고 후에 읽을 수 있다.
state와 비슷하게 느껴질 수 있지만 중요한 차이가 있음
→ ref는 화면 출력에 영향을 주지 않는 정보를 저장하기에 적합
ref의 값을 바꾸려면, current 속성에 직접 대입해서 수동으로 변경해야 합니다.
ref가 보장하는 것
- 다시 렌더링할 때마다 정보를 저장(일반 변수는 렌더링할 때마다 재설정)
- 이를 변경해도 다시 렌더링이 트리거되지 않음 (다시 렌더링을 트리거하는 상태 변수와는 다름)
- 해당 정보는 구성 요소의 각 사본에 로컬로 저장(공유되는 외부 변수와는 다름)
ref 내용 재생성 방지
function Video() {
const playerRef = useRef(new VideoPlayer());
// ...
new VideoPlayer()최초 렌더링에만 사용되지만 모든 렌더링에서 이 함수를 호출하게 됨
→비용이 많이 드는 객체를 생성하는 경우 이는 낭비일 수 있다.
이 문제를 해결하려면 다음과 같이 참조를 초기화할 수 있다.
function Video() {
const playerRef = useRef(null);
if (playerRef.current === null) {
playerRef.current = new VideoPlayer();
}
// ...
null체커기 만드는 법
useRef(null)로 생성시 myRef.current의 타입은 null일 수도 있고 실제 값일 수도 있음
TypeScript를 사용할 경우 해당 ref 사용할 때마다 타입 체커가 자꾸 null 체크에 대해 경고함
이렇게 자꾸 null값에 경고를 받을 바에 확실하게 해당 ref값이 null이 아님을 보장해주는 함수를 따로 만들것을 권장
function Video() {
const playerRef = useRef(null);
function getPlayer() {
if (playerRef.current !== null) {
return playerRef.current;
}
const player = new VideoPlayer();
playerRef.current = player;
return player;
}
React는 렌더링 출력(render output)에 맞춰 자동으로 DOM을 업데이트한다 그래서 컴포넌트에서 직접 DOM을 조작할 필요 없다. 하지만 React가 관리하는 DOM elements에 접근해야할 때가 있다.
→ 예를 들어 focusr a node, 스크롤, 크기와 위치를 측정할 때 등.
React에는 이러한 작업을 수행할 수 있는 기본 제공 기능이 없으므로 DOM 노드에 대한 ref가 필요하다.
