TIL 52 / 53일차 : REACTJS 숙련 : React Hooks 3 - useRef

minjun kim·2024년 12월 2일
0

1. useRef란?

✨ 값을 저장하고 활용하는 방법 중 useState와 비교되는 useRef!

1-1. useRef hook 소개

useState와 더불어 특정 값을 저장하기 위해 사용되는 대표적인 hook입니다.
`Re-rendering과 상관없이 값을 기억하기 위해 사용되는 것이 본질적 특징입니다.

이 특징을 이용해 자바스크립트 DOM API를 직접사용하지 않고
DOM 요소를 다루기 위한 용도로도 자주 사용됩니다.

1-2. 사용방법

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에는 값이 담겨있다.

ref {current: '초기값'}

그리고 변경도 가능합니다.

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 {current: '초기값'}
ref {current: '바꾼 값'}

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

이러한 특징 때문에 useRef는 다음 2가지 용도로 사용되는데

(1) 저장공간

1. state와 비슷한 역할을 해요. 
다만 state는 변화가 일어나면 다시 렌더링이 일어납니다.
내부 변수들은 초기화가 가능합니다.
2. ref에 저장한 값
3. 컴포넌트가 100번 렌디렁되면 -> ref에 저장된 값은 유지가 됩니다.
4. 따라서
a. state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰면 된다.
b. ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용한다.

(2) DOM

  1. 렌더링 되자마자 특정 inputfocusing 돼야 하는 등,
    DOM 요소를 핸들링해야 하는 순간이 나면 useRef를 사용하는 것이 좋은 선택지가 됩니다.

2. 예제 코드로 확인하기

✨ 조금 더 깊은 활용도를 알아보자

2-1. state와 ref의 차이점

위에서 설명드렸던 stateref의 차이점을 살펴보자

plusStateCountButtonHandler와, plusRefCountButtonHandler
다르게 동작하는걸 확인해보자

state는 변경되면 렌더링이 되고, ref는 변경되면 렌더링이 되지 않습니다.

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;

그러나 내부 변수는 let 키워드로 선언해서 변수 사용이 가능한가요?

let 키워드를 사용하게 되면 렌더링 시 어떻게 되냐면
다시 변수가 초기화 되는데 이유는 함수이기 때문입니다.

2-2. DOM 접근

<input/> 태그에는 ref라는 속성이 있는데,
이걸 통해 해당 DOM 요소로 접근이 가능합니다. 코드로 살펴보면

// 사용할 화면을 만들어주고
import "./App.css";

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

export default App;

여기서 화면이 렌더링 되고나서 아이디에 자동 포커싱 되게 할 수 없을까요?

// useRef 사용하여 포커싱 주기
import "./App.css";

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

export default App;

위에서 하면 화면이 렌더링 되자마자 바로 foucs가 들어가진다.

그렇다면 아이디가 10자리 입력되면 자동으로
비밀번호 필드로 이동하도록 코드를 구현해보면

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

function App() {
  const idRef = useRef("");
  const pwRef = useRef("");

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

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

  // 렌더링이 될 때
  useEffect(() => {
    idRef.current.focus();
  }, []);

  // 왜 useEffect 안에 놓았을까요?
  useEffect(() => {
    if (id.length >= 10) {
      pwRef.current.focus();
    }
  }, [id]);

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

export default App;

그럼 여기서 id.length >= 10 이 로직을 useEffect 안에 왜 넣었을까?
당연히 우리가 아이디가 10자리 입력되면 자동으로 비밀번호 필드로 이동하도록
그러니 한번만 useEffect를 사용하면 자동으로 넘어가지 않는다.

그래서 useEffectid.length >= 10 으로 조건을 걸어서
id의 길이가 10과 같거나 넘으면 pwRef.current.focus(); 가 실행되게 하는 것이다.

0개의 댓글

관련 채용 정보