2023.02.10
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 이다.
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가지 용도로 사용된다.
plusStateCountButtonHandler와, plusRefCountButtonHandler는 다르게 동작한다는걸 알아보자.
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;
#2. useRef 사용하여 포커싱 주기
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();
}, []);
// 아이디가 10자리 이상 입력되면 자동으로 비밀번호 필드로 이동하는 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;