[학습 목표]
1. useRef hook에 대해 학습하게 돼요.
2. 저장공간으로서의 useRef, DOM요소 접근 방법으로서의 useRef의 활용방법을 배우게 돼요.
DOM 요소에 접근할 수 있도록 하는 React Hook 이에요.
HTML과 javascript를 사용했을 때 우리는 특정 DOM을 선택하기 위해서 다음과 같이 했었죠.
// (1) getElementById 이용
const divTag = document.getElementById('#myDiv');
// (2) querySelector 이용
const divTag2 = document.querySelector('#myDiv');
리액트에서도 DOM을 선택해야 할 상황이 생기기 마련이에요. 예를 들면 화면이 렌더링 되자마자 특정 input 태그가 focusing이 돼야 하는 경우 등이요. 그럴 경우에 우리는 useRef hook을 사용합니다.
useRef hook은 다음과 같이 사용해요.
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에는 값이 이렇게 담겨있어요.

그리고, 변경도 가능해요!
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 값은 컴포넌트가 계속해서 렌더링 되어도 unmount 전까지 값을 유지합니다!
이러한 특징 때문에 useRef는 다음 2가지 용도로 사용됩니다.
위에서 설명드렸던 state와 ref의 차이점을 코드를 통해 살펴보기로 하죠!
plusStateCountButtonHandler와, plusRefCountButtonHandler는 다르게 동작하는게 이해가 되시나요?
state는 변경되면 렌더링이 되고, ref는 변경되면 렌더링이 안된다는걸 다시 한번 기억해주세요 😎
App.jsx
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;
<input /> 태그에는 ref라는 속성이 있습니다. 이걸 통해 우리는 해당 DOM 요소로 접근할 수 있어요.
코드로 살펴볼까요?
#1. 사용할 화면 만들어주기
import "./App.css";
function App() {
return (
<>
<div>
아이디 : <input type="text" />
</div>
<div>
비밀번호 : <input type="password" />
</div>
</>
);
}
export default App;
간단하게 아이디와 비밀번호를 입력받는 구조를 만들어봤어요.

그런데, 화면이 렌더링 되고나면 아이디에 자동 포커싱 되게 할 순 없을까요?
위 코드에서 아이디가 10자리 입력되면 자동으로 비밀번호 필드로 이동하도록 코드를 짜보세요.
import React, { useEffect, useRef, useState } from "react";
function App() {
// useRef 사용해서 패스워드에 포커싱하기
const passwordRef = useRef("");
const [id, setId] = useState("");
const onChangeIdHandler = (event) => {
setId(event.target.value);
};
// 화면이 렌더링 될때, 어떤 작업을 하고 싶다 : useEffect!!
useEffect(() => {
if (id.length >= 10) {
passwordRef.current.focus();
}
}, [id]);
return (
<>
<div>
아이디 : <input type="text" value={id} onChange={onChangeIdHandler} />
</div>
<div>
비밀번호 : <input type="password" ref={passwordRef} />
</div>
</>
);
}
export default App;