인프런 커뮤니티 질문&답변

Dohun Choi님의 프로필 이미지
Dohun Choi

작성한 질문수

처음 만난 리액트(React)

useMemo, useCallback, useRef

useRef가 잘 이해되지 않습니다.

해결된 질문

작성

·

623

1

useRef() Hook의 다음 코드에서 질문이 있습니다.

useRef는 DOM에 접근하기 위해 사용하는 Hook으로 이해하면 될까요?

예시 코드에서

<input type="text" ref={inputElem} />

inputElem을 해당 input태그에 접근하기 위해 useRef를 사용하는 것이 맞나요?

useRef() Hook이 데이터 변경을 감지하지 못해서 HTML 코드에 있는 ref의 변경을 감지할 수 있는 useCallback() Hook을 대신 사용하는게 맞나요?

그럼 useCallback을 useRef를 대체하여 사용가능한 건가요?

답변 1

1

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

안녕하세요, 소플입니다.

useRef() 훅은 일반적으로 DOM element에 접근하기 위해서 사용합니다.

그래서 특정 element에 대해 reference를 하기 위한 목적이라는 뜻에서 훅의 이름이 useRef()인 것이라고 이해하시면 됩니다.

그래서 작성해주신 코드에서 inputElem은 input element에 접근하기 위해 사용하는 것이 맞습니다.

 

하지만 useRef() 훅은 단순히 특정 element에 reference를 하기 위해서만 사용하는 것이 아니라,

리액트 함수 컴포넌트 내부에서 렌더링과 관계없는 값을 저장하기 위한 용도로도 많이 사용합니다.

예를 들면, 아래와 같이 컴포넌트를 작성하게 되면 MyComponent가 렌더링 될 때마다 value라는 변수가 매번 재할당 됩니다.

import { useRef } from 'react';

function MyComponent() {
    const value = 0;

    return <div>Hello, world!</div>;
}

export default MyComponent;

이말은 곧 reference가 변경된다고도 할 수 있으며,

만약 useEffect(), useMemo() 등의 훅의 dependency array에 해당 변수를 넣게 되면 매번 값이 변한 것으로 판단한다는 뜻이기도 합니다.

그래서 이러한 상황을 방지하고 렌더링과 관계없이 값을 저장하기 위한 용도로 useRef() 훅을 아래와 같이 사용합니다.

import { useRef } from 'react';

function MyComponent() {
    const value = useRef(0);

    return <div>Hello, world!</div>;
}

export default MyComponent;

 

그리고 useRef() 훅을 사용할 경우 해당 element의 렌더링 시점에 별도로 callback을 받을 수 없습니다.

그렇기 때문에 만약 element가 렌더링 되는 시점에 원하는 동작을 실행하고 싶다면 Callback Ref 라고 부르는 방식을 사용해야 합니다.

이 방식은 ref에 reference 객체가 아닌 함수를 넣어서 해당 element가 렌더링 된 이후에 수행하고 싶은 작업들을 함수 내부 구현하는 것입니다.

정리하면, element의 ref 속성에는 useRef() 훅으로 생성한 reference 객체 또는 함수를 넣을 수 있다 라고 이해하시면 됩니다.

아래 리액트 공식 문서를 참고하시면 이해하는데 더 도움이 되실 겁니다.

https://react.dev/reference/react-dom/components/common#ref-callback

 

감사합니다.

Dohun Choi님의 프로필 이미지
Dohun Choi
질문자

답변 감사합니다.
useRef() Hook에 대해서 이해가 잘 되었습니다.

추가적으로 조금 헷갈리는 게 있습니다.
Callback ref라는 방식을 사용한다는 게 useRef() Hook을 사용하는 것이 아닌 ref 태그에 useCallback() Hook을 사용하여 ref 속성의 변경을 감지할 수 있게한다는 것으로 이해했는데 맞나요?

(여기서 말하는 ref가 useRef() HOOK이 아닌 DOM에서 쓰이는 ref 속성을 의미하는 것일까요? 처음에 Callback ref가 useRef() Hook을 사용한다고 이해했었는데 그게 아닌거 같습니다...ㅎ)

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

네, 맞습니다.

Callback Ref 방식은 DOM element의 ref 속성에 함수를 사용하는 형태라고 이해하시면 됩니다.

여기서 Callback이라는 용어 때문에 약간 헷갈리실 수도 있는데,

여기 이름에서의 Callback은 그냥 함수를 의미한다고 생각하시면 됩니다.

참고로 아래 코드는 useCallback() 훅을 사용하지 않고 Callback Ref를 사용한 형태입니다.

function MyComponent() {
    return (
        <div
            ref={(node) => {
                console.log(node);
            }}>
            Hello, world!
        </div>
    );
}

export default MyComponent;

 

그렇기 때문에 꼭 useCallback() 훅으로 만든 함수를 사용해야 하는 것은 아니지만,

대부분의 경우에 아래와 같이 useCallback() 훅을 사용합니다.

import { useCallback } from 'react';

function MyComponent() {
    const myRef = useCallback((node) => {
        console.log(node);
    }, []);

    return <div ref={myRef}>Hello, world!</div>;
}

export default MyComponent;
Dohun Choi님의 프로필 이미지
Dohun Choi

작성한 질문수

질문하기