[React] 4-4장 | useRef의 역할과 사용법

Re_Go·2024년 6월 9일
0

React

목록 보기
8/10
post-thumbnail

1. useState와 useRef의 차이

useStateuseRef는 리액트에서 컴포넌트 내부의 상태값을 저장하는 변수로 사용된다는대에 동일점을 가지고 있습니다.

하지만 이러한 동일점을 가지고 있어도 그 쓰임새가 다른 만큼 useState를 두고 굳이 useRef가 만들어지지 않았겠죠?

useRef가 useState에 차이점을 두는 주요 부분은 변경에 의한 리렌더링을 발생시키지 않는다는 것
에 그 차이점을 둘 수 있습니다.

import { useState } from 'react';

function Counter() {
  // useState를 사용하여 count 상태를 선언합니다.
  const [count, setCount] = useState(0);

  const onClickButton = (val) => {
    setCount(count + val) 
    console.log(count)
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => onClickButton(1)}>Increment</button>
      <button onClick={() => onClickButton(-1)}>Decrement</button>
    </div>
  );
}

export default Counter;

위 코드에서는 useState를 이용해 간단한 스테이츠를 하나 만들어 컴포넌트를 제어하는 예제인데요. 위 count에 변화를 주면 이에 따라 페이지가 새로 리렌더링 되는 당연한 결과가 발생합니다.

import { useRef } from 'react';

function Counter() {
  // useState를 사용하여 count 상태를 선언합니다.
  const reference = useRef(0)

  const onClickButton = (val) => {
    reference.current += val
    console.log(reference.current);
  };

  return (
    <div>
      <p>reference: {reference.current}</p>
      <button onClick={() => onClickButton(1)}>Increment</button>
      <button onClick={() => onClickButton(-1)}>Decrement</button>
    </div>
  );
}

export default Counter;

반면 useRef의 경우는 다른데, 위의 예제는 useRef를 useState처럼 사용하고자 하는 예제인데요. 그러나 앞서 말씀드린 차이점대로 렌더링이 실시간으로 반영된 useState와는 달리 useRef는 렌더링이 실시간으로 반영이 되지 않는다는 점을 알 수 있습니다.

그래서 리렌더링 분기점을 만들거나, 페이지를 새로고침 할때에야 비로소 리렌더링 되는 모습을 보이는 거죠.

  1. useState를 사용한 경우

  1. useRef를 사용한 경우

그리고 또 출력된 콘솔에서 유추해 볼 수 있는 사실은, useState의 경우 렌더링이 실시간으로 반영된다고 하더라도 실제 useState의 state 값은 이전의 상태값
을 갖고 있는데 반해,

useRef의 경우 이전의 상태값이 아니라 즉각적인 상태값의 변화를 반영
하고 있기 때문에 앞서 소개해드린 생애 주기에서 자주 사용되는 훅이라는 점도 알 수 있죠.

2. DOM 요소 제어를 위한 참조 객체로서의 활용

앞서 소개한 useRef는 또 다른 활용법을 가지고 있는데요. 바로 DOM 요소의 제어에 사용될 수 있다는 점입니다.

import { useState, useRef } from 'react';

function Counter() {
  // useState를 사용하여 count 상태를 선언합니다.
  const [count, setCount] = useState(0);

  // useState를 사용하여 input 필드의 값을 저장합니다.
  const [inputValue, setInputValue] = useState('');

  // useRef를 사용하여 input 요소를 참조합니다.
  const inputRef = useRef(null);

  const onClickButton = (val) => {
    setCount(count + val);
  };

  // 발생한 이벤트의 key가 'Enter', 즉 사용자가 엔터키를 눌렀을 때
  const onEnterPress = (e) => {
    if (e.key === 'Enter') {
      // 현재 해당 돔 요소를 참조하고 있는 inputRef의 current (DOM)의 value (e.target.value 와 같음)의 값을 inputValue에 대입
      setInputValue(inputRef.current.value);
    }
  };
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => onClickButton(1)}>Increment</button>
      <button onClick={() => onClickButton(-1)}>Decrement</button>
      <input ref={inputRef} type="text" placeholder="Type something" onKeyDown={onEnterPress} />
       {/* inputValue의 현재 상태값 출력 */}
      <p>Input value: {inputValue}</p>
    </div>
  );
}

export default Counter;

이때 useRef의 활용을 보면 input이라는 DOM 요소를 참조하고 있는 요소로 활용되어 실제 이벤트(Enter)가 발생될 때 참조하고 있는 DOM 요소의 value를 제공하는 역할을 수행하고 있습니다.

이처럼 useRefDOM 요소의 참조를 저장하는 역할로도 활용
될 수 있습니다.

profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글