React-19

최광희·2023년 12월 22일

React

목록 보기
19/44

React Hooks - useRef

[학습 목표]
1. useRef hook에 대해 학습하게 돼요.
2. 저장공간으로서의 useRef, DOM요소 접근 방법으로서의 useRef의 활용방법을 배우게 돼요.

1. useRef란?

(1) useRef hook 소개

DOM 요소에 접근할 수 있도록 하는 React Hook 이에요.
HTML과 javascript를 사용했을 때 우리는 특정 DOM을 선택하기 위해서 다음과 같이 했었죠.

// (1) getElementById 이용
const divTag = document.getElementById('#myDiv');

// (2) querySelector 이용
const divTag2 = document.querySelector('#myDiv');

리액트에서도 DOM을 선택해야 할 상황이 생기기 마련이에요. 예를 들면 화면이 렌더링 되자마자 특정 input 태그가 focusing이 돼야 하는 경우 등이요. 그럴 경우에 우리는 useRef hook을 사용합니다.

(2) 사용방법(새로운 프로젝트를 만들어서 해봅시다.)

useRef hook은 다음과 같이 사용해요.

import "./App.css";
import { useRef } from "react";

function App() {
  const ref = useRef("초기값");
  console.log("ref", ref);

  return (
    <div>
      <p>useRef에 대한 이야기에요.</p>
    </div>
  );
}

export default App;

콘솔을 확인해보면, ref에는 값이 이렇게 담겨있어요.

그리고, 변경도 가능해요!

import "./App.css";
import { useRef } from "react";

function App() {
  const ref = useRef("초기값");
  console.log("ref 1", ref);

  ref.current = "바꾼 값";
  console.log("ref 1", ref);

  return (
    <div>
      <p>useRef에 대한 이야기에요.</p>
    </div>
  );
}

export default App;

(중요) 이렇게 설정된 ref 값은 컴포넌트가 계속해서 렌더링 되어도 unmount 전까지 값을 유지합니다!

이러한 특징 때문에 useRef는 다음 2가지 용도로 사용됩니다.

  1. 저장공간
    1. state와 비슷한 역할을 해요. 다만 state는 변화가 일어나면 다시 렌더링이 일어나요. 내부 변수들은 초기화가 되죠.
    2. ref에 저장한 값은 렌더링을 일으키지 않아요. 즉, ref의 값 변화가 일어나도 렌더링으로 인해 내부 변수들이 초기화 되는 것을 막을 수 있죠.
    3. 컴포넌트가 100번 렌더링 → ref에 저장한 값은 유지돼요.
    4. 정리하면
      1. state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰면 된다.
      2. ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용한다.
  2. DOM
    1. 설명 초반에 말씀드렸던 부분이에요! 렌더링 되자마자 특정 input이 focusing 돼야 한다면 useRef를 사용하면 됩니다.

2. 예제 코드로 특징 살펴보기

(1) state와 ref의 차이점

위에서 설명드렸던 state와 ref의 차이점을 코드를 통해 살펴보기로 하죠!

plusStateCountButtonHandler와, plusRefCountButtonHandler는 다르게 동작하는게 이해가 되시나요?

state는 변경되면 렌더링이 되고, ref는 변경되면 렌더링이 안된다는걸 다시 한번 기억해주세요 😎

App.jsx

import "./App.css";
import { useRef, useState } from "react";

function App() {
  const [count, setCount] = useState(0);
  const countRef = useRef(0);

  const plusStateCountButtonHandler = () => {
    setCount(count + 1);
  };

  const plusRefCountButtonHandler = () => {
    countRef.current++;
  };

  return (
    <>
      <div>
        state 영역입니다. {count} <br />
        <button onClick={plusStateCountButtonHandler}>state 증가</button>
      </div>
      <div>
        ref 영역입니다. {countRef.current} <br />
        <button onClick={plusRefCountButtonHandler}>ref 증가</button>
      </div>
    </>
  );
}

export default App;

(2) DOM 접근

<input /> 태그에는 ref라는 속성이 있습니다. 이걸 통해 우리는 해당 DOM 요소로 접근할 수 있어요.

코드로 살펴볼까요?

#1. 사용할 화면 만들어주기

import "./App.css";

function App() {
  return (
    <>
      <div>
        아이디 : <input type="text" />
      </div>
      <div>
        비밀번호 : <input type="password" />
      </div>
    </>
  );
}

export default App;

간단하게 아이디와 비밀번호를 입력받는 구조를 만들어봤어요.

그런데, 화면이 렌더링 되고나면 아이디에 자동 포커싱 되게 할 순 없을까요?

미션!

위 코드에서 아이디가 10자리 입력되면 자동으로 비밀번호 필드로 이동하도록 코드를 짜보세요.

import React, { useEffect, useRef, useState } from "react";

function App() {
  // useRef 사용해서 패스워드에 포커싱하기
  const passwordRef = useRef("");

  const [id, setId] = useState("");

  const onChangeIdHandler = (event) => {
    setId(event.target.value);
  };

  // 화면이 렌더링 될때, 어떤 작업을 하고 싶다 : useEffect!!
  useEffect(() => {
    if (id.length >= 10) {
      passwordRef.current.focus();
    }
  }, [id]);

  return (
    <>
      <div>
        아이디 : <input type="text" value={id} onChange={onChangeIdHandler} />
      </div>
      <div>
        비밀번호 : <input type="password" ref={passwordRef} />
      </div>
    </>
  );
}

export default App;
profile
나는 사람들을 치료해주는 '약'과 같은 존재가 되고 싶다.

0개의 댓글