프로그래밍/React

[React] useRef

라다디 2022. 5. 8. 17:13

 

useRef로 특정 DOM 선택

자바스크립트에서 특정 DOM을 선택해야 하는 경우, getElementById, querySelector과 같은 DOM selector 함수를 사용했다.

리액트를 사용하는 프로젝트에서도 DOM을 직접 선택해야 하는 상황이 있다. 

 

  • 특정 input에 포커스 주기
  • 특정 엘리먼트 크기 가져오기
  • 스크롤바 위치 가져오거나 설정
  • Canvas 요소에 그리 그리기 등

이러한 경우에 DOM에 직접적으로 접근하기 위해 ref를 사용한다. 

 

더보기

서로 다른 컴포넌트끼리 데이터를 교류할 때 ref를 사용한다면 이는 잘못 사용된 것이다.

사용은 가능하지만 리액트 사상에 어긋난 설계이다.

컴포넌트끼리 데이터를 교류할 때는 언제나 데이터를 부모 ↔ 자식 흐름으로 교류해야 한다. 

 

이러한 ref를 함수 컴포넌트에서는 useRef Hook을 이용하여 쉽게 사용할 수 있게 해준다. 

useRef를 사용하여 ref를 설정하면 useRef를 통해 만든 객체 안의 current 값이 실제 엘리먼트를 가리킨다. 

import React, { useState, useRef } from 'react';

function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });
  const nameInput = useRef();

  const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출

  const onChange = e => {
    const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
    setInputs({
      ...inputs, // 기존의 input 객체를 복사한 뒤
      [name]: value // name 키를 가진 값을 value 로 설정
    });
  };

  const onReset = () => {
    setInputs({
      name: '',
      nickname: ''
    });
    nameInput.current.focus();
  };

  return (
    <div>
      <input
        name="name"
        placeholder="이름"
        onChange={onChange}
        value={name}
        ref={nameInput}
      />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;

useRef()를 사용하여 ref 객체를 만들고, 이 객체를 선택하고자 하는 DOM의 ref 값으로 설정한다. (35행)

그러면 ref 객체의 .curret 값은 선택하고자 했던 DOM을 가리키게 된다. 

 

위 예제에서는 25행에 input에 포커스를 하는 focus() DOM API를 호출했다. 

따라서 초기화 버튼을 클릭할 시에 이름 input에 포커스가 잡히게 된다. 

 

useRef로 컴포넌트 안의 변수 만들기

useRef는 DOM을 선택하는 용도 외에도 다른 용도가 한가지 더 있다. 바로 컴포넌트 안에서 조회 및 수정할 수 있는 변수를 관리하는 것이다. 

 

 

Hooks FAQ – React

A JavaScript library for building user interfaces

reactjs.org

 

useRef로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않는다.

리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고 렌더링이 된 이후로 업데이트된 상태를 조회할 수 있는 반면, useRef 로 관리하고 있는 변수는 설정 후 바로 조회할 수 있다.

 

import React, { useRef } from "react";

const RefSample = () => {
  const id = useRef(1);
  const setId = (n) => {
    id.current = n;
  };
  const printId = () => {
    console.log(id.current);
  };
  return <div>refsample</div>;
};

export default RefSample;

useRef를 사용할 때 파라미터를 넣어주면, 이 값이 .current 값의 기본값이 된다.

값을 수정할 때는 .current 값을 수정하면 되고, 조회할 때는 .current값을 조회하면 된다.

 

다시 한 번 강조하지만 ref 안의 값이 바뀌어도 컴포넌트는 렌더링되지 않는다. 

 


📌 아래 문서와 서적의 내용을 정리한 글입니다.