비공식 사이트. 24.12.31. 폐쇄예정
공식사이트 바로가기

useRef is a React Hook that lets you reference a value that’s not needed for rendering. useRef는 렌더링에 필요하지 않은 값을 참조할 수 있는 React 훅입니다.

const ref = useRef(initialValue)

Reference참조

useRef(initialValue)

Call useRef at the top level of your component to declare a ref. 컴포넌트의 최상위 레벨에서 useRef를 호출하여 ref를 선언합니다.

import { useRef } from 'react';

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

See more examples below. 아래에서 더 많은 예시를 확인하세요.

Parameters매개변수

  • initialValue: The value you want the ref object’s current property to be initially. It can be a value of any type. This argument is ignored after the initial render. initialValue: ref 객체의 current 프로퍼티 초기 설정값입니다. 여기에는 어떤 유형의 값이든 지정할 수 있습니다. 이 인자는 초기 렌더링 이후부터는 무시됩니다.

Returns반환값

useRef returns an object with a single property: useRef는 단일 프로퍼티를 가진 객체를 반환합니다:

  • current: Initially, it’s set to the initialValue you have passed. You can later set it to something else. If you pass the ref object to React as a ref attribute to a JSX node, React will set its current property. current: 처음에는 전달한 initialValue로 설정됩니다. 나중에 다른 값으로 바꿀 수 있습니다. ref 객체를 JSX 노드의 ref 속성으로 React에 전달하면 React는 current 프로퍼티를 설정합니다.

On the next renders, useRef will return the same object. 다음 렌더링에서 useRef는 동일한 객체를 반환합니다.

Caveats주의사항

  • You can mutate the ref.current property. Unlike state, it is mutable. However, if it holds an object that is used for rendering (for example, a piece of your state), then you shouldn’t mutate that object. ref.current 프로퍼티는 state와 달리 변이할 수 있습니다. 그러나 렌더링에 사용되는 객체(예: state의 일부)를 포함하는 경우 해당 객체를 변이해서는 안 됩니다.

  • When you change the ref.current property, React does not re-render your component. React is not aware of when you change it because a ref is a plain JavaScript object. ref.current 프로퍼티를 변경해도 React는 컴포넌트를 다시 렌더링하지 않습니다. ref는 일반 JavaScript 객체이기 때문에 React는 사용자가 언제 변경했는지 알지 못합니다.

  • Do not write or read ref.current during rendering, except for initialization. This makes your component’s behavior unpredictable. 초기화를 제외하고는 렌더링 중에 ref.current를 쓰거나 읽지 마세요. 이렇게 하면 컴포넌트의 동작을 예측할 수 없게 됩니다.

  • In Strict Mode, React will call your component function twice in order to help you find accidental impurities. This is development-only behavior and does not affect production. Each ref object will be created twice, but one of the versions will be discarded. If your component function is pure (as it should be), this should not affect the behavior. Strict Mode에서 React는 컴포넌트 함수를 두 번 호출하여 의도하지 않은 불순물을 찾을 수 있도록 돕습니다. 이는 개발 환경 전용 동작이며 상용 환경에는 영향을 미치지 않습니다. 각 ref 객체는 두 번 생성되고 그 중 하나는 버려집니다. 컴포넌트 함수가 순수하다면(그래야 합니다), 컴포넌트의 로직에 영향을 미치지 않습니다.


Usage사용법

Referencing a value with a ref ref로 값 참조하기

Call useRef at the top level of your component to declare one or more refs. 컴포넌트의 최상위 레벨에서 useRef를 호출하여 하나 이상의 ref를 선언합니다.

import { useRef } from 'react';

function Stopwatch() {
const intervalRef = useRef(0);
// ...

useRef returns a ref object with a single current property initially set to the initial value you provided. useRef는 처음에 제공한 초기값으로 설정된 단일 current 프로퍼티가 있는 ref 객체를 반환합니다.

On the next renders, useRef will return the same object. You can change its current property to store information and read it later. This might remind you of state, but there is an important difference. 다음 렌더링에서 useRef는 동일한 객체를 반환합니다. 정보를 저장하고 나중에 읽을 수 있도록 current 속성을 변경할 수 있습니다. state가 떠오를 수 있지만, 둘 사이에는 중요한 차이점이 있습니다.

Changing a ref does not trigger a re-render. This means refs are perfect for storing information that doesn’t affect the visual output of your component. For example, if you need to store an interval ID and retrieve it later, you can put it in a ref. To update the value inside the ref, you need to manually change its current property: ref를 변경해도 리렌더링을 촉발하지 않습니다. 즉,ref는 컴포넌트의 시각적 출력에 영향을 미치지 않는 정보를 저장하는 데 적합합니다. 예를 들어, interval ID를 저장했다가 나중에 불러와야 하는 경우 ref에 넣을 수 있습니다. ref 내부의 값을 업데이트하려면 current 프로퍼티를 수동으로 변경해야 합니다:

function handleStartClick() {
const intervalId = setInterval(() => {
// ...
}, 1000);
intervalRef.current = intervalId;
}

Later, you can read that interval ID from the ref so that you can call clear that interval: 나중에 ref에서 해당 interval ID를 읽어 해당 interval을 취소할 수 있습니다:

function handleStopClick() {
const intervalId = intervalRef.current;
clearInterval(intervalId);
}

By using a ref, you ensure that: ref를 사용하면 다음을 보장합니다:

  • You can store information between re-renders (unlike regular variables, which reset on every render). (렌더링할 때마다 재설정되는 일반 변수와 달리) 리렌더링 사이에 정보를 저장할 수 있습니다.

  • Changing it does not trigger a re-render (unlike state variables, which trigger a re-render). (리렌더링을 촉발하는 state 변수와 달리) 변경해도 리렌더링을 촉발하지 않습니다.

  • The information is local to each copy of your component (unlike the variables outside, which are shared). (정보가 공유되는 외부 변수와 달리) 각각의 컴포넌트에 로컬로 저장됩니다.

Changing a ref does not trigger a re-render, so refs are not appropriate for storing information you want to display on the screen. Use state for that instead. Read more about choosing between useRef and useState. ref를 변경해도 다시 렌더링되지 않으므로 화면에 표시되는 정보를 저장하는 데는 ref가 적합하지 않습니다. 대신 state를 사용하세요. 더 자세한 내용은 useRefuseState 중 선택하기에서 확인하세요.

Examples of referencing a value with useRefuseRef로 값을 참조하는 예시

Example 1 of 2: Click counter counter 클릭하기

This component uses a ref to keep track of how many times the button was clicked. Note that it’s okay to use a ref instead of state here because the click count is only read and written in an event handler. 이 컴포넌트는 ref를 사용하여 버튼이 클릭된 횟수를 추적합니다. 클릭 횟수는 이벤트 핸들러에서만 읽고 쓰기 때문에 여기서는 state 대신 ref를 사용해도 괜찮습니다.

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>
  );
}

If you show {ref.current} in the JSX, the number won’t update on click. This is because setting ref.current does not trigger a re-render. Information that’s used for rendering should be state instead. JSX에 {ref.current}를 표시하면 클릭 시 번호가 업데이트되지 않습니다. ref.current를 설정해도 리렌더링을 촉발하지 않기 때문입니다. 렌더링에 사용하는 정보는 ref가 아닌 state여야 합니다.

Pitfall | 함정

Do not write or read ref.current during rendering. 렌더링 중에는 ref.current를 쓰거나 읽지 마세요.

React expects that the body of your component behaves like a pure function: React는 컴포넌트의 본문이 순수 함수처럼 동작하기를 기대합니다:

  • If the inputs (props, state, and context) are the same, it should return exactly the same JSX. 입력값들(props, state, context)이 동일하면 완전히 동일한 JSX를 반환해야 합니다.

  • Calling it in a different order or with different arguments should not affect the results of other calls. 다른 순서나 다른 인수를 사용하여 호출해도 다른 호출의 결과에 영향을 미치지 않아야 합니다.

Reading or writing a ref during rendering breaks these expectations. 렌더링 중에 ref를 읽거나 쓰면 이러한 기대가 깨집니다.

function MyComponent() {
// ...
// 🚩 Don't write a ref during rendering
// 🚩 렌더링 중에 ref를 작성하지 마세요.
myRef.current = 123;
// ...
// 🚩 Don't read a ref during rendering
// 🚩 렌더링 중에 ref를 읽지 마세요.
return <h1>{myOtherRef.current}</h1>;
}

You can read or write refs from event handlers or effects instead. 대신 이벤트 핸들러나 Effect에서 ref를 읽거나 쓸 수 있습니다.

function MyComponent() {
// ...
useEffect(() => {
// ✅ You can read or write refs in effects
// ✅ Effect에서 ref를 읽거나 쓸 수 있습니다.
myRef.current = 123;
});
// ...
function handleClick() {
// ✅ You can read or write refs in event handlers
// ✅ 이벤트 핸들러에서 ref를 읽거나 쓸 수 있습니다.
doSomething(myOtherRef.current);
}
// ...
}

If you have to read or write something during rendering, use state instead. 렌더링 중에 무언가를 읽거나 써야 하는 경우, 대신 state를 사용하세요.

When you break these rules, your component might still work, but most of the newer features we’re adding to React will rely on these expectations. Read more about keeping your components pure. 컴포넌트는 이러한 규칙을 어기더라도 여전히 작동할 수도 있지만, React에 추가되는 대부분의 새로운 기능들은 이러한 기대에 의존합니다. 자세한 내용은 컴포넌트를 순수하게 유지하기에서 확인하세요.


Manipulating the DOM with a ref ref로 DOM 조작하기

It’s particularly common to use a ref to manipulate the DOM. React has built-in support for this. ref를 사용하여 DOM을 조작하는 것은 특히 일반적입니다. React에는 이를 위한 기본 지원이 있습니다.

First, declare a ref object with an initial value of null: 먼저 초기값nullref 객체를 선언하세요:

import { useRef } from 'react';

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

Then pass your ref object as the ref attribute to the JSX of the DOM node you want to manipulate: 그런 다음 ref 객체를 ref 속성으로 조작하려는 DOM 노드의 JSX에 전달하세요:

// ...
return <input ref={inputRef} />;

After React creates the DOM node and puts it on the screen, React will set the current property of your ref object to that DOM node. Now you can access the <input>’s DOM node and call methods like focus(): React가 DOM 노드를 생성하고 화면에 그린 후, React는 ref 객체의 current프로퍼티를 DOM 노드로 설정합니다. 이제 DOM 노드 <input> 접근해 focus()와 같은 메서드를 호출할 수 있습니다.

function handleClick() {
inputRef.current.focus();
}

React will set the current property back to null when the node is removed from the screen. 노드가 화면에서 제거되면 React는 current 프로퍼티를 다시 null로 설정합니다.

Read more about manipulating the DOM with Refs. 자세한 내용은 ref로 DOM 조작하기에서 알아보세요.

Examples of manipulating the DOM with useRefuseRef로 DOM을 조작하는 예시

Example 1 of 4: Focusing a text input 텍스트 input에 초점 맞추기

In this example, clicking the button will focus the input: 이 예제에서는 버튼을 클릭하면 input에 초점이 맞춰집니다:

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}


Avoiding recreating the ref contents ref 콘텐츠 재생성 피하기

React saves the initial ref value once and ignores it on the next renders. React는 초기에 ref 값을 한 번 저장하고, 다음 렌더링부터는 이를 무시합니다.

function Video() {
const playerRef = useRef(new VideoPlayer());
// ...

Although the result of new VideoPlayer() is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating expensive objects. new VideoPlayer()의 결과는 초기 렌더링에만 사용되지만, 호출 자체는 이후의 모든 렌더링에서도 여전히 계속 이뤄집니다. 이는 값비싼 객체를 생성하는 경우 낭비일 수 있습니다.

To solve it, you may initialize the ref like this instead: 이 문제를 해결하려면 대신 다음과 같이 ref를 초기화할 수 있습니다:

function Video() {
const playerRef = useRef(null);
if (playerRef.current === null) {
playerRef.current = new VideoPlayer();
}
// ...

Normally, writing or reading ref.current during render is not allowed. However, it’s fine in this case because the result is always the same, and the condition only executes during initialization so it’s fully predictable. 일반적으로 렌더링 중에 ref.current를 쓰거나 읽는 것은 허용되지 않습니다. 하지만 이 경우에는 결과가 항상 동일하고 초기화 중에만 조건이 실행되므로 충분히 예측할 수 있으므로 괜찮습니다.

Deep Dive | 심층 탐구

How to avoid null checks when initializing useRef later useRef를 초기화할 때 null 검사를 피하는 방법

If you use a type checker and don’t want to always check for null, you can try a pattern like this instead: 타입 검사기를 사용하면서 항상 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;
}

// ...

Here, the playerRef itself is nullable. However, you should be able to convince your type checker that there is no case in which getPlayer() returns null. Then use getPlayer() in your event handlers. 여기서 playerRef 자체는 nullable합니다. 하지만 타입 검사기에 getPlayer()null을 반환하는 경우가 없다는 것을 확신시킬 수 있어야 합니다. 그런 다음 이벤트 핸들러에서 getPlayer()를 사용하십시오.


Troubleshooting문제 해결

I can’t get a ref to a custom component 커스텀 컴포넌트에 대한 ref를 얻을 수 없습니다

If you try to pass a ref to your own component like this: 컴포넌트에 ref를 전달하고자 다음과 같이 하면:

const inputRef = useRef(null);

return <MyInput ref={inputRef} />;

You might get an error in the console: 다음과 같은 오류가 발생할 것입니다:

Console
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? 경고: 함수 컴포넌트에는 ref를 지정할 수 없습니다. 이 ref에 접근하려는 시도는 실패합니다. React.forwardRef()를 사용하려고 하셨나요?

By default, your own components don’t expose refs to the DOM nodes inside them. 기본적으로 컴포넌트는 내부의 DOM 노드에 대한 ref를 외부로 노출하지 않습니다.

To fix this, find the component that you want to get a ref to: 이 문제를 해결하려면 ref를 가져오고자 하는 컴포넌트를 찾으세요:

export default function MyInput({ value, onChange }) {
return (
<input
value={value}
onChange={onChange}
/>
);
}

And then wrap it in forwardRef like this: 그런 다음 다음과 같이 forwardRef로 감싸세요:

import { forwardRef } from 'react';

const MyInput = forwardRef(({ value, onChange }, ref) => {
return (
<input
value={value}
onChange={onChange}
ref={ref}
/>
);
});

export default MyInput;

Then the parent component can get a ref to it. 그러면 부모 컴포넌트가 ref를 가져올 수 있습니다.

Read more about accessing another component’s DOM nodes. 자세한 내용은 다른 컴포넌트의 DOM 노드에 접근하기에서 확인하세요.