useRef 알아보기

우동이·2022년 6월 13일
0

React

목록 보기
3/7
post-thumbnail
post-custom-banner

useRef 알아보기

  • useRef는 특정 DOM을 선택해야할 때 주로 사용되는 Hook 입니다.
    • 주로 함수형 컴포넌트에서 사용되며 클래스형 컴포넌트에서는 React.createRef를 사용해야 합니다.
  • 또한 전역으로 변수를 관리할 수 있습니다.
    • useRef 는 일반적인 자바스크립트 객체입니다.
      • heap 영역에 저장되는 변수를 의미
    • 리렌더링이 발생할 때마다 동일한 객체를 제공합니다.
    • 값이 변경되어도 리렌더링이 발생되지 않습니다.
      • 같은 메모리 주소를 참조하고 있기 때문에 변경사항을 감지할 수 없습니다.
    • useRef로 선언한 변수는 리렌더링을 발생시키지 않고 리렌더링이 발생해도 이전의 값을 기억하며, 컴포넌트마다 고유의 값을 가질 수 있습니다.

1. useRef 사용해보기 - DOM 접근

  • useRef는 전달된 인자(초기값)을 바탕으로 변경 가능한 ref 객체를 반환합니다.
    • .current를 통해 적용한 DOM Eelement에 접근할 수 있게 됩니다.
  • 해당 Input 태그는 컴포넌트가 리렌더링이 발생하면 포커스를 가지게 됩니다!
import React, { useEffect, useRef } from "react";

const Main = () => {
  // useRef Hook으로 ref 객체 생성
  const input = useRef();

  useEffect(() => {
    // input element에 접근
    input.current.focus();
  });

  return (
    <div>
      <h1>메인 페이지</h1>
      <hr />
      {/* ref 객체 적용 */}
      <input name="name" placeholder="이름" ref={input} />
    </div>
  );
};

export default Main;

2. useRef 사용해보기 - 변수 활용

  • useRef로 관리하는 변수는 값이 변경되도 컴포넌트가 리렌더링이 발생하지 않습니다.
    • 즉 변수값이 변경되면 바로 조회할 수 있습니다.
  • 아래의 코드에서 nextId.current의 값은 버튼을 클릭할 때마다 내부적인 값은 증가하지만 리렌더링이 발생하지 않아 화면에서는 그대로 숫자 1만 보여지게 됩니다.
import React, { useEffect, useRef } from "react";

const Main = () => {
  // useRef Hook으로 ref 객체 생성
  const nextId = useRef(1);

  const handleCreateIndex = () => {
    nextId.current += 1;
    // 1 / 2 / 3 / 4.... ( 값 계속 증가 )
    console.log(nextId.current);
  };

  return (
    <div>
      <h1>메인 페이지</h1>
      {/* 값 1 고정 */}
      <div>{nextId.current}</div>
      <button onClick={handleCreateIndex}>index 증가</button>
    </div>
  );
};

export default Main;

3. 컴포넌트가 Unmount 될 때 특정 State의 작업 진행

  • 기존의 useState를 활용하게 되면 useEffect의 dependency가 빈 배열임으로 최신의 데이터를 참조할 수 없어 마지막에 숫자 0을 출력
import React, { useEffect, useState } from "react";

const Main = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    return () => {
      // 숫자 0 출력
      console.log("Unmount", count);
    };
  }, []);

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

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={handleIncreaseCount}>+</button>
    </div>
  );
};

export default Main;
  • useRef를 통해 개선 가능
import React, { useEffect, useState, useRef } from "react";

const Main = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(count);

  useEffect(() => {
    // count state가 변경되면 ref 객체 업데이트
    countRef.current = count;
  }, [count]);

  useEffect(() => {
    return () => {
      // React 생명주기와 독립적으로 값이 유지됨으로 최신의 count를 출력 
      console.log("Unmount", countRef.current);
    };
  }, []);

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

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={handleIncreaseCount}>+</button>
    </div>
  );
};

export default Main;

참고 자료

profile
아직 나는 취해있을 수 없다...
post-custom-banner

0개의 댓글