useRef는 렌더링에 필요하지 않은 값을 참조할 수 있는 React Hook입니다.
const ref = useRef(initialValue)
useRef(initialValue)
컴포넌트의 최상위 레벨에서 useRef를 호출하여 ref를 선언한다.
import { useRef } from 'react';
function MyComponent() {
const intervalRef = useRef(0);
const inputRef = useRef(null);
// ...
매개변수
- initialValue : ref 객체의 current 프로퍼티 초기 설정값이다. 어떤 유형의 값이든 지정할 수 있고 이 인자는 초기 렌더링 이후부터는 무시된다.
반환값
useRef는 단일 프로퍼티를 가진 객체를 반환한다.
- current : 처음에는 전달한 initialValue로 설정된다. 나중에 다른 값으로 바꿀 수 있고, ref 객체를 jsx 노드의 ref 어트리뷰트로 전달하면 current 프로퍼티를 설정한다.
주의할점으로는
- ref.current 프로퍼티는 state와 달리 변이할 수 있다. 그러나 렌더링에 사용되는 객체를 포함하는 경우 해당 객체를 변이해서는 안된다.
- ref.current 프로퍼티를 변경해도 리렌더링이 일어나지 않는다. ref는 일반 js객체이기 때문에 React는 언제 변경했는지 알지 못한다.
- 초기화를 제외하고는 ref.current 를 쓰거나 읽지 않아야 한다.
- Strict Mode에서 두 번 호출하여 의도하지 않은 불순물을 찾을 수 있도록 도와준다.
사용법
ref로 값 참조하기
컴포넌트의 최상위 레벨에서 useRef를 호출해 선언한다.
import { useRef } from 'react';
function Stopwatch() {
const intervalRef = useRef(0);
// ...
ref 내부의 값을 업데이트 하려면 current 프로퍼티를 수동으로 변경해야 한다.
function handleStartClick() {
const intervalId = setInterval(() => {
// ...
}, 1000);
intervalRef.current = intervalId;
}
나중에 ref에서 해당 interval ID를 읽어 취소할 수 있다.
function handleStopClick() {
const intervalId = intervalRef.current;
clearInterval(intervalId);
}
ref를 사용하면..
- 리렌더링 사이에 정보를 저장할 수 있다.
- 변경해도 리렌더링을 촉발하지 않는다.
- 각각의 컴포넌트에 로컬로 저장된다.
ref로 DOM 조작하기
먼저 초기값이 null인 ref객체를 선언
import { useRef } from 'react';
function MyComponent() {
const inputRef = useRef(null);
// ...
그런 다음 ref 객체를 ref 속성으로 조작하려는 DOM 노드의 jsx에 전달
// ...
return <input ref={inputRef} />;
그 이후 <input> 접근해 focus()같은 메서드를 호출할 수 있다
function handleClick() {
inputRef.current.focus();
}
노드가 화면에서 제거되면 React는 current 프로퍼티를 다시 null로 설정
ref 콘텐츠 재생성 피하기
React는 초기에 ref 값을 한 번 저장하고, 다음 렌더링부터는 이를 무시한다.
function Video() {
const playerRef = useRef(new VideoPlayer());
// ...
값비싼 객체를 생성하는 경우 낭비일 수 있다.
function Video() {
const playerRef = useRef(null);
if (playerRef.current === null) {
playerRef.current = new VideoPlayer();
}
// ...
일반적으로는 렌더링 중에 ref.current 를 쓰거나 읽는 것은 허용되지 않는다. 하지만 이 경우에는 결과가 항상 동일하고 초기화 중에만 조건이 실행되므로 충분히 예측할 수 있어 괜찮다.
컴포넌트에 ref를 전달하고자 다음과 같이 하면
const inputRef = useRef(null);
return <MyInput ref={inputRef} />;

이런 오류가 발생할 것이다.
기본적으로 컴포넌트는 내부의 DOM 노드에 대한 ref를 외부로 노출하지 않는다.
export default function MyInput({ value, onChange }) {
return (
<input
value={value}
onChange={onChange}
/>
);
}
이랬던 코드를 forwardRef로 감싸준다.
import { forwardRef } from 'react';
const MyInput = forwardRef(({ value, onChange }, ref) => {
return (
<input
value={value}
onChange={onChange}
ref={ref}
/>
);
});
export default MyInput;
그러면 부모 컴포넌트가 ref를 가져올 수 있다.
'리액트 공식문서 읽어보기' 카테고리의 다른 글
| useCallback (0) | 2024.03.02 |
|---|---|
| <Suspense> (1) | 2024.02.25 |
| lazy (0) | 2024.02.25 |
| useState (0) | 2024.02.24 |
| useMemo (0) | 2024.02.22 |