본문 바로가기

040. React 입문 - useRef로 컴포넌트의 변수 생성하기

codeConnection 2024. 5. 22.

개념

useStateuseRef는 컴포넌트 내부에서 변수처럼 사용한다는 점은 동일하지만 useRef는 값이 변하더라도 컴포넌트를 재 렌더링 하지 않는다는 점이 큰 차이다.

그리고 useRef는 DOM 요소를 직접적으로 선택이 가능하다. 마치 자바스크립트에서 querySelector를 사용한 것과 비슷하다.

사용법

import 하기

import { useState } from "react";
import { useRef } from "react";

그런데 보통 useState는 무조건 사용할 테니, 출처가 같은 hook은 서로 중괄호 하나로 묶을 수 있다.

import { useState, useRef } from "react";

초기값 지정하기

const refObj = useRef(0);
console.log(refObj); // {current: 0}
console.log(refObj.current); // 0

useRef는 current라는 key를 갖는 객체 형태이다. 여기에 값을 할당하면 current의 value로 할당된다.

객체이기 때문에 점 표기법으로 .current 라는 key에 접근하면 값만 얻을 수 있다.

어디에 사용?

재 렌더링이 되면 안 되는 기능에다가 넣을 수 있다. 예를 들어 사용자에게 값을 입력받는 input이 있고 여기에 onChange 이벤트 핸들러를 달아 놨다면, 사용자가 타이핑 할 때마다 state의 값이 변하면서 재 렌더링이 발생할 것이다.

화면에 굳이 렌더링 할 필요가 없는 정보라면 굳이 값이 변할 때마다 컴포넌트를 재 렌더링 시키는 useState 훅을 사용할 필요가 없다. 불필요한 메모리 낭비다.

즉 화면에 재 렌더링을 해줘야 하는 상태는 useState 훅을, 화면에 재 렌더링을 할 필요가 없는 상태는 메모리 절약을 위해 useRef를 사용하면 된다.

실제 웹 개발에서 대부분의 상황은 특정 DOM 요소를 가리킬 때 많이 사용한다.

// useRef 훅을 사용하여 입력 필드에 포커스를 주는 방법
import React, { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <div>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>입력필드에 포커스 주기</button>
    </div>
  );
}

export default TextInputWithFocusButton;

회원가입 페이지를 만들 때 사용자가 특정 값을 입력하지 않았다면, 예를 들어서 ID를 입력하지 않았다면 ID를 입력하는 칸으로 포커스를 옮길 수 있다.

import { useRef, useState } from 'react'; // 같은 출처라면 동시에 임포트 가능

function App() {
    const inputRef = useRef(null); // inputRef 선언
    const [userId, setUserId] = useState(''); // userId와 setUserId 선언

    const onSubmit = (e) => {
        e.preventDefault(); // 폼 제출 시 페이지 리로드 방지
        if (userId === '') { // userId가 빈 문자열일 때
            inputRef.current.focus(); // inputRef를 통해 input에 포커스
        }
    }

    return (
        <>
            <div>
                <form onSubmit={onSubmit}>
                    <label>아이디 : </label>
                    <input
                        ref={inputRef} // inputRef 연결
                        type="text"
                        value={userId} // userId 값 설정
                        onChange={(e) => setUserId(e.target.value)} // 값 변경 시 setUserId 호출
                    />
                    <button type="submit">가입하기</button>
                </form>
            </div>
        </>
    )
}

export default App; // App 컴포넌트 내보내기

댓글