React Custom Component(2) UseRef

HanSungUk·2022년 6월 30일
0

React

목록 보기
6/13
post-thumbnail

React Custom Component(2) UseRef

현재 코드스테이츠 강의를 통해 프론트엔드를 학습하고 있습니다.
본 포스트는 해당 강의에 대한 내용 정리를 목적으로 합니다.

학습목표

  • useRef의 필요성에 대해 학습한다.
  • useRef가 필요한 상황들을 기억한다.
  • useRef의 사용법을 이해한다.

1. useRef란 무엇인가

React는 아래와 같이 DOM 엘리먼트의 주소값을 활용해야 하는 경우 사용하는 Hook이 있습니다.

  • focus
  • text selection
  • media playback
  • 애니메이션 적용
  • d3.js, greensock 등 DOM 기반 라이브러리 활용

React는 이런 예외적인 상황에서 useRef로 DOM 노드, 엘리먼트, 그리고 React 컴포넌트 주소값을 참조할 수 있습니다.
아래 예시 코드처럼 작성하면 주소값을 활용할 수 있습니다.

const 주소값을_담는_그릇 = useRef(참조자료형)
// 이제 주소값을_담는_그릇 변수에 어떤 주소값이든 담을 수 있습니다.
return(
	<div>
  		<input ref={주소값을_담는_그릇} type="text"/>
  	{/* React에서 사용 가능한 ref라는 속성에 주소값을_담는_그릇을 값으로 할당하면*/}
    {/* 주소값을_담는_그릇 변수에는 input DOM 엘리먼트의 주소가 담깁니다. */}
    {/* 향후 다른 컴포넌트에서 input DOM 엘리먼트를 활용할 수 있습니다. */}
    </div>);
)

이 주소값은 컴포넌트가 재렌더링 되더라도 바뀌지 않습니다.

React 컴포넌트는 기본적으로 내부 상태(state)가 변할 때마다 다시 렌더링(rendering)됩니다.

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

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

  const increaseCountState = () => {
    setCount(count + 1);
    console.log("state:", count);
  };

  const increaseCountRef = () => {
    countRef.current = countRef.current + 1;
    console.log("Ref :", countRef.current); //countRef.current
  };
  return (
    <div>
      <p>State: {count}</p>
      <p>Ref: {countRef.current}</p>
      <button onClick={increaseCountState}>State 올려</button>
      <button onClick={increaseCountRef}>Ref 올려</button>
    </div>
  );
}

아래 예제에서는 state가 증가할 때마다 App 컴포넌트가 재렌더링 되기 때문에 콘솔창에서 'state 올려' 버튼을 클릭한 횟수만큼 다시 렌더링이 되는 걸 확인할 수 있습니다.
반면에 'Ref 올려' 버튼을 클릿한 횟수는 콘솔창에 보이지만 브라우저 상에서는 확인할 수 없다는 걸 확인할 수 있습니다.
useRef는 아무리 수정을 해도 해당 컴포넌트를 다시 렌더링시키지 않기 때문입니다.
App 컴포넌트 내부적으로는 countRef객체가 증가하고 있는 것은 맞지만 렌더링이 되지 않고 있기 때문에 아무리 증가해도 브라우저에 보이지 않습니다.

이 상태에서 다시 'state 올려' 버튼을 누른다면 App 컴포넌트가 렌더링되면서 countRef의 값도 업데이트가 된 걸 확인할 수 있습니다.

위 내용을 정리하면 아래와 같습니다.

  • 저장공간
    state의 변화 -> 렌더링 -> 컴포넌트 내부 변화들 초기화
    Ref의 변화 -> No 렌더링 => 변수들의 값이 유지됨
    state의 변화 -> 렌더링 -> 그래도 Ref의 값은 유지됨

렌더링이 되지 않는다는 특징으로 인해 useRef 통해 성능 향상을 시킬 수 있습니다.

또한 useRef를 이용해 DOM 요소에 접근할 수 있습니다.
대표적으로는 input요소를 클릭하지 않아도 focus()를 주고 싶을 때 많이 사용합니다.

2. useRef 사용하기

useRef함수는 current속성을 가지고 있는 객체를 반환하는데, 인자로 넘어온 초기값을 current 속성에 할당합니다. 이 current속성은 값을 변경해도 상태를 변경할 때처럼 React 컴포넌트가 다시 렌더링되지 않습니다.
React 컴포넌트가 다시 렌더링될 때에도 current속성의 값은 사라지지 않습니다.

// 기본 형태
const ref = useRef(value)
// ref 객체
{current: value}

// 예시
const ref = useRef("hi")
// ref 객체
{current: "hi"}
// ref 객체
ref.current = "hello"
{current: "hello"}

아래의 코드처럼 렌더링이 될때마다 실행되는 useEffect 함수에서도 useRef를 사용함으로써 재렌더링되지 않게 할 수 있습니다.
만약 useEffect안에 useState를 사용했다면 계속 렌더링되는 상황이 발생할 수도 있습니다.

useRef를 이용해 DOM 요소에 접근하는 방법은 useRef를 접근하고자하는 DOM 요소에 넣어주기만 하면 됩니다. 아래 코드를 통해 input요소에 접근했다면 value값도 사용할 수 있습니다.

const ref = useRef(value)
// useRef를 접근하고자하는 DOM 요소에 넣어주기만 하면 됩니다.
<input ref={ref}/>

0개의 댓글