리액트에서 DOM 엘리먼트의 주소값을 활용해야 하는 예외적인 경우 useRef
로 DOM 노드, 엘리먼트, 그리고 React 컴포넌트 주소값을 참조할 수 있다.
useRef를 사용하는 예외적인 경우
- focus
- text selection
- media playback
- 애니메이션 적용
- d3.js, greensock 등 DOM 기반 라이브러리 활용
useRef 를 남용하는 것은 부적절하고, React의 특징이자 장점인 선언형 프로그래밍 원칙과 배치되기 때문에, 조심해서 사용해야한다.
import {useRef} from "react";
const App = () => {
const divRef = useRef(null) // 변수에 useRef를 담아
return (
<div className="App">
<div ref={divRef}></div> // 원하는 HTML DOM element 에 속성으로 넣어준다.
</div>
);
}
export default App;
const 변수 = useRef(value) 를 사용하면 current 프로퍼티를 가지고 있는 {current: value}
객체를 반환한다.
위 코드에서 divRef 변수는 {current: <div></div>}
를 담고 있다.
값을 useRef
, useState
, let
(또는 const
)을 사용해서 저장하는 것에는 각각 차이가 있다.
useState를 사용해 저장한 값(=상태)는 setState로 값이(=상태가) 변할 때마다 렌더링이 일어난다.
반면에 useRef를 사용해 저장한 값은 ref.current 값에 변화가 생겨도 렌더링이 일어나지 않는다.
위 코드에서 `State up` 버튼을 누르면 값의 변화를 즉시 화면에서 확인할 수 있지만
`Ref up` 버튼을 누르면 화면에는 아무런 변화가 없다.
하지만 콘솔창을 확인해보면 Ref 로 저장한 값도 값이 변한 것을 확인할 수 있다.
이때 `State up` 버튼을 눌러 화면 렌더링이 발생하면, 변화된 Ref 값을 화면에서 확인할 수 있다.
값이 변할 때마다 화면 렌더링은 굳이 필요하지는 않을 때 useRef를 사용하면 렌더링 최적화에 이를 수 있다.
값을 일반 변수에 저장해도, 변수의 값이 변할 때마다 화면이 렌더링되지 않는다.
하지만 일반 변수에 저장하는 것과 useRef 사용의 가장 큰 차이는
변수에 저장한 값은 화면이 렌더링이 되면 초기화된다는 것이다.
위 코드에서 `Ref up`과 `Var up` 버튼을 누르면 둘 다 화면에서 값의 변화를 확인할 수 없다.
하지만 콘솔창을 올려 확인해보면 둘 다 값이 변한 것을 확인할 수 있다.
이 때 `State up` 버튼을 눌러 화면 렌더링이 발생하면,
변화된 Ref 값은 화면에서 확인할 수 있지만,
Var 값은 초기화 되어 0이 된다.
리액트는 함수형 컴포넌트로 렌더링이 일어날 때마다 함수를 새로 호출하기 때문에, 함수 안의 모든 변수들이 초기화 된다.
useRef의 또 다른 특징은 DOM 요소에 직접 접근할 수 있다는 것이다.
⚠️ 사용시 주의할 점 :
조건부 렌더링으로 컴포넌트가 사라지거나 하는 경우 값이 없을 수도 있으므로 if(inputRef.current)
로 값이 있는지 확인하고 사용하는 것이 권장된다.
input 요소를 누르지 않아도 커서가 input창에 포커스 되어 있어서 바로 입력하도록 만들기
inputRef.current.focus();
코드 설명
① 첫 화면 렌더링되었을 때 때 입력창에 커서가 focus 되도록 useEffect()에 inputRef.current.focus()
를 사용했다.
② input창에 입력 후 로그인을 누르면 입력창의 값(value)이 알림창으로 뜨도록 버튼 클릭 함수 popupHandler() 에서 inputRef.current.value
로 input 엘리먼트의 value를 가져와서 사용했다.
③ 마지막으로 알림창을 닫은 후에도 input 창에 커서가 포커스 되도록 popupHandler()에서 한번 더 inputRef.current.focus()
를 사용햇다.
참고 자료 : React Hooks에 취한다 - useRef 완벽 정리 1# 변수 관리 | 리액트 훅스 시리즈
React Hooks에 취한다 - useRef 완벽 정리 2# DOM 요소 접근 | 리액트 훅스 시리즈
코드스테이츠 유어클래스