useRef

김동현·2021년 12월 7일
1

React

목록 보기
11/27
post-thumbnail
post-custom-banner

useRef 훅

ref는 reference의 약어로서 리액트에서는 일반적으로 "DOM 요소로 직접 엑세스"해서 작업할 수 있게 해주는 역할을 합니다.

JSX 문법의 "ref 어트리뷰트"와 리액트 훅인 "useRef 훅"을 사용하여 렌더링될 "HTML 돔 노드"와 "자바스크립트 코드" 간의 연결을 만들 수 있습니다.

useRef 훅은 컴포넌트를 작성하다가 "돔 노드를 직접 다루어야 하는 경우"에 사용합니다. 돔 요소 노드를 직접 다루기 위해서document.getElementById()와 같은 DOM API를 사용하여 돔 노드를 직접 다룰 수 있지만 이 방법은 리액트답지 않습니다.

useRef로 돔 노드 객체 접근하기

useRef 훅은 react 라이브러리에서 제공하는 훅으로 모든 다른 리액트 훅처럼 컴포넌트 함수 내부에서만 사용할 수 있습니다.

useRef 훅은 항상 "일반 객체"를 반환하며, 반환되는 객체에는 "current 라는 프로퍼티"만이 존재합니다.

useRef 훅이 반환한 객체를 연결할 HTML 태그 이름을 JSX로 사용한 곳에 "ref" 어트리뷰트 값으로 작성하여 연결할 수 있습니다.
이후 객체의 current 프로퍼티에는 ref 어트리뷰트로 연결된 "실제 돔 노드 객체"가 바인딩되어 있습니다.

// 1. useRef 훅을 사용하여 ref 객체 생성
const nameRef = useRef();

// 2. HTML 태그 이름을 JSX로 작성한 경우에만 ref 어트리뷰트 값으로 useRef 훅이 반환한 객체 작성하여 연결 가능
<HTMLTagName ref={nameRef}></HTMLTagName>

생성된 ref 객체의 current 프로퍼티는 컴포넌트의 생명주기와는 독립적으로 유지됩니다.
즉, 컴포넌트가 재실행되어 리렌더링되더라도 ref.current 값은 변경되지 않고 유지됩니다. 또한 ref.current 값을 명시적으로 변경하더라도 컴포넌트가 리렌더링되지도 않습니다.


import React, { useRef } from 'react';

const MyComponent = () => {
    // ref 생성하여 inputRef에 바인딩
    const inputRef = useRef();
    
    const submitHandler = event => {
        event.preventDefault();
        console.log(inputRef); // -> { current: input }
    };
    
    return (
        <form onSubmit={submitHandler}>
            // ref prop에 inputRef 전달하여 연결
            <input ref={inputRef} />
        </form>
    );
}

위 코드에서 input 엘리먼트의 ref 어트리뷰트에는 useRef 훅으로 생성한 inputRef를 작성하여 연결을 설정하고, submit 이벤트가 발생하면 inputRef 객체를 콘솔창에 출력하도록 하였습니다.

inputRef를 콘솔창에 출력하면 다음과 같은 내용이 출력됩니다.

inputRef 객체에는 current라는 프로퍼티가 존재하며 current 프로퍼티에는 "실제 돔 요소 노드인 input 노드 객체"가 바인딩되어 있습니다.

즉, 우리는 inputRef.current를 사용하여 "돔 요소 노드를 직접 접근"할 수 있습니다.

ref 어트리뷰트는 빌트인 어트리뷰트로서 특수한 목적을 위해 사용합니다. 즉, 일반적인 데이터를 전달하기 위한 용도의 어트리뷰트로 사용할 수 없습니다.

useRef로 변수 관리하기

useRef 훅 호출시 반환되는 객체의 current 프로퍼티 값은 컴포넌트 생명주기와 독립적으로 유지되는 값입니다. 즉, 생명주기에 영향을 받지 않는 값을 관리하기 위해서 사용할 수도 있습니다.

또한 state와는 달리 current 값이 변경된다고 해서 컴포넌트가 리렌더링되지도 않습니다.

useRef 훅 인수로 current 프로퍼티에 바인딩될 값을 전달하면서 호출시 반환되는 객체의 current 프로퍼티에는 인수로 전달된 값이 존재하게 됩니다.

const Component = () => {
    const ref = useRef(0);

    const addClickHandler = () => {
        ref.current += 1;
        consol.log(ref);
    };
    
    return <button onClick={addClickHandler}>ADD</button>;
};

버튼 클릭시 ref.current 값 1씩 증가하게 됩니다. 이때 컴포넌트가 재평가되더라도 ref.current 값은 기존 값으로 유지하게 되며 값이 변경되더라도 컴포넌트가 재평가되지도 않습니다.

profile
Frontend Dev
post-custom-banner

0개의 댓글