React

리액트 useRef란

hihiha2 2023. 2. 28. 20:33

🤩 useRef 🤩

useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지될 것입니다.

 

useRef는 리액트 훅의 한 종류로, Ref는 reference(참조)의 줄임말이다. 

useRef를 이용하면 특정한 DOM요소에 접근이 가능하면, 불필요한 재렌더링을 하지 않는다는 장점이 있다.

 

 

1. 형식

1️⃣ 생성

const 변수명 = useRef(초기값)

useRef는 변수명에 초기값을 적는 식으로 만든다.

 

➡️ 이러한 결과값으로, {current:  초기값}  을 지닌 객체가 반환된다.

 

useRef에서 기억할 것은 이러한 current라는 키값을 지닌 프로퍼티가 생성되고, 값에 어떤 변경을 줄때도 이 current를 이용해서 한다는 점이다.

 

2️⃣ 반환요소에 접근

<input ref= {변수명}/>

 

2. 특징

 반환된 useRef 객체는 컴포넌트의 전생애주기를 통해 유지가 된다. 

1️⃣(= 컴포넌트가 계속해서 렌더링이 되어도 컴포넌트가 언마운드되기 전까지는 값을 그대로 유지할 수 있다)

2️⃣(= currnet 속성은 값을 변경해도 상태를 변경할 때 처럼 React 컴포넌트가 재렌더링 되지 않는다. )

 

🔫 렌더링과 상관없이, 마운트된 시점부터 언마운트된 시점까지 값을 유지한다 🔫 

 

3. 언제 사용?

1️⃣  저장공간

ref는 state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.

State의 변화 ➡️ 렌더링 ➡️ 컴포넌트 내부 변수들 초기화
Ref의 변화 ➡️ No 렌더링 ➡️ 변수들의 값이 유지됨
State의 변화 ➡️ 렌더링 ➡️ 그래도 Ref의 값은 유지됨

변경시 렌더링을 발생시키지 말아야하는 값을 다룰때 사용한다

(변화는 감지해야하지만, 그 변화가 렌더링을 발생시키면 안될때!!)

 

 

2️⃣  DOM요소에 접근

✅ useRef를 사용하면 손쉽게 input에 접근할 수 있다.

바닐라 자바스크립트의 getElementById, querySelector와 비슷하다.

 

<DOM요소 접근의 대표적인 예>

대표적으로 Input요소를 클릭하지 않아도 focus를 줄때 사용

 

 

4. 장점

자주 변경되는 값을 state에 담으면, 변경될때마다 재렌더링이 일어나서 성능에 안좋은 영향을 미친다.

하지만 useRef를 이용하면 값이 변경될때마다 렌더링이 일어나지 않는다 ➡️ ⭐️ 성능향상!! ⭐️

 

 

5. 일반 변수와의 차이점

state는 변경될때마다 재렌더링이 일어나고, ref는 변경이 되어도 렌더링이 일어나지 않는다는 점을 알았다.

그러면 일반

변수에서 선언한 값과는 어떤 차이가 있을까?

 

const countVar = 0; 이라는 변수를 선언하고 버튼을 누르면 그값에 +1을 하는 함수를 만들었다고 해보자.

const App = () => {

const countVar = 0;

const increaseVar = () => {
countVar = countVar +1;
}

return (
<div>
<p>Var: {countVar} </p>
<button onClick={increaseVar}> Var올려 </button>
</div>
)

Var올려 버튼을 누르고 렌더링을 해주면 var는 몇이 나올까?

정답은 0이다.

 

렌더링을 해준다는 것은 함수를 처음부터 다시 실행한다는 것을 의미한다.

그래서 렌더링을 할때마다 App컴포넌트를 나타내는 함수가 다시 불린다. 그러면 함수가 불릴때마다 이 함수 내부에 있는 변수들이 다시 초기화가 된다. 

 

따라서 렌더링이 될때마다 const countVar = 0; 를 통해서 countVar라는 변수에는 계속해서 0으로 초기화가 된다.

🤔 useRef훅을 이용한 값과의 비교
ref의 값은 컴포넌트의 전생애주기를 통해서 관리되기 때문에, 아무리 컴포넌트가 렌더링 되더라도 언마운트가 되기 전까지는 값을 계속해서 유지한다.

✅ ref는 렌더링이후에도 값이 유지되지만, 변수는 초기화된다.

 

 

5. 대표적인 예시

input요소에 focus를 주고 싶을때 많이 사용한다.

ex>로그인 화면에서 id를 입력하는 칸을 클릭하지 않아도 자동적으로 focus가 되어있게 해주면, 키보드만 사용해도 바로 id를 입력할 수 있어서 편리하다.

 

리셋버튼을 누르면 맨앞에 있는 input에 focus가 들어가는 코드를 짜도록 해보자.

앞서서 input여러개 관리하기 연습한 코드에 이어서 만들어보았다.

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

const InputSample = () => {
  const [inputs, setInputs] = useState({
    이름: "",
    nickname: "",
  });

  const nameFocus = useRef();

  const { 이름, nickname } = inputs;

  const onChange = (e) => {
    const { value, name } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };

  const onReset = () => {
    setInputs({
      이름: "",
      nickname: "",
    });
    nameFocus.current.focus();
  };
  return (
    <div>
      <input
        name="이름"
        placeholder="이름쓰세요"
        onChange={onChange}
        value={이름}
        ref={nameFocus}
      />
      <input
        name="nickname"
        placeholder="닉네임쓰세요"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값:</b>
        {이름}({nickname})
      </div>
    </div>
  );
};

export default InputSample;

1️⃣  const nameFocus = useRef();

nameFocus라는 변수명을 지어서 useRef()의 초기값을 빈값으로 할당하였다.

 

2️⃣  onReset 함수안에 nameFocus.current.focus()

 const onReset = () => {
    setInputs({
      이름: "",
      nickname: "",
    });
    nameFocus.current.focus();
  };

onReset를 누르면

useRef를 통해 만든 객체인 nameFocus안에 current에 focus()를 준다.

 

3️⃣ input안에 ref 속성값으로 {변수명}을 적는다.

      <input
        name="이름"
        placeholder="이름쓰세요"
        onChange={onChange}
        value={이름}
        ref={nameFocus}
      />

실제로 focus가 일어날 input에 ref라는 속성을 통해 변수명을 전달한다.

 

초기화버튼을 눌렀을때, 위와같이 focus버튼이 첫번째 input에 생긴것을 확인해볼수있다.

 

 

useRef란 무엇인지, 그 특징과 사용이유를 중점으로 공부해보았다.

렌더링을 계속해서 발생시키지 않기때문에 성능에 도움이 될 수 있고, ref를 이용해서 쉽게 DOM요소에 접근할 수 있다는 것이 흥미로웠다.

앞으로 프로젝트를 하면서 또 사용해보고 추후에 알게 된 점이 있다면 블로그에 기록해둬야겠다.

 

 

🤓 useRef 요약 🤓

//생성 
const 변수명 = useRef(초기값)
// {current: 초기값} 을 지닌 객체가 반환됨 

//반환요소에 접근
<input ref={변수명}/>

1️⃣ 변화는 감지하지만 렌더링 발생 X ➡️  성능향상 (state는 변화시, 재렌더링됨)

2️⃣ DOM요소에 손쉽게 접근 (ref속성 사용)

3️⃣ 전생애주기를 통해 유지 (언마운트 되기전까지는 값을 계속 기억함)

 

 

 

 

참고자료

React Hooks에 취한다 - useRef 완벽 정리 1# 변수 관리 | 리액트 훅스 시리즈 (별코딩)

React Hooks에 취한다 - useRef 완벽 정리 2# DOM 요소 접근 | 리액트 훅스 시리즈(별코딩)

useRef로 특정 DOM 선택하기 (벨로퍼트와 함께하는 모던 리액트)

React 공식사이트