웹 애플리케이션은 HTML, CSS, JavaScript로 구성되어 있고, DOM은 웹 페이지의 구조와 콘텐츠를 표현하는 객체모델이다.
const li = document.querySelector('span');
li.textContent = "hello world";
이렇게 바닐라 JS로 적는 것이 DOM 직접 조작하는 방법이다.
바닐라 JS처럼 순수 JavaScript를 사용하면 DOM 조작을 할 수 있다.
하지만 DOM을 직접 조작하는 것은 단점이 있다.
일반적으로 웹 애플리케이션에서 DOM 조작은 비용이 많이 들고, 느린 작업 중 하나다. DOM의 변경은 웹 페이지를 다시 렌더링하고 리플로우(reflow)및 리페인트(repaint)작업을 수행해야 한다. 이는 성능 저하로 이어진다.
이러한 단점 때문에 등장한 것이 가상 DOM이다.
가상 DOM(Virtual DOM)은 웹 애플리케이션의 성능을 향상시키기 위한 개념이다. 가상 DOM은 메모리에 존재하는 가벼운 복사본으로, 실제 DOM과 대응하는 구조다. 웹 애플리케이션에서 상태 변화가 발생하면 가상 DOM을 업데이트하고, 변경사항을 실제 DOM를 반영하기 전에 가상 DOM과 실제 DOM 간의 차이점을 비교한다.
이 차이 비교 과정에서 최소한의 DOM 조작만 수행되므로 성능이 향상된다. 변경 사항이 있는 부분만 업데이트되고, 리플로우와 리페인트 작업이 최소화된다. 이를 통해 웹 애플리케이션의 반응성을 향상시키고 사용자 경험을 개선할 수 있다.
React와 같은 UI 라이브러리/프레임워크는 가상 DOM을 활용하여 성능을 최적하고, 상태와 UI의 동기화를 효과적으로 관리함으로써 직접 DOM 조작의 단점을 보완한다.
React 같은 라이브러리나 프레임워크는 위와 같은 이유로 가상 DOM을 사용한다는 것을 알았다. 이렇게 라이브러리나 프레임워크는 DOM을 직접 조작하는 것을 지양한다. 하지만 DOM 객체가 필요한 상황이 계속 발생한다. 그래서 탄생한 것이 React Hook인 useRef다.
useRef와 useState는 React에서 상태를 다루는 두가지 주요 훅이다. 각각의 용도와 사용 시나리오가 다르기 때문에 어떤 훅을 사용해야 할지는 사용하려는 데이터의 특성과 목적에 따라 결정되어야 한다.
- DOM 요소나 컴포넌트 인스턴스와 같은 변하지 않는 값을 저장하고 유지하는 데 사용된다.
- 이전 값과 현재 값을 비교하고자 할 때 사용될 수 있다.
- 컴포넌트의 렌더링과 관련 없는 값을 저장하고자 할 때 사용된다.
useState는 컴포넌트의 상태를 관리하고, 상태 변경 시 컴포넌트를 다시 렌더링한다. 상태 변경은 렌더링을 트리거하므로 컴포넌트의 상태에 의존하는 뷰를 업데이트한다.
반대로 useRef는 컴포넌트의 렌더링과 상관없이 값을 저장하고 유지하며, 값이 변경되어도 컴포넌트를 다시 렌더링하지 않는다. 따라서 useRef는 일반적으로 렌더링과 무관한 데이터를 관리할 때 사용된다.
const refContainer = useRef(initialValue);
위와 같이 주소값을 담을 공간을 만든다. 초기값을 넣어 줄 수 있다.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
<input>에 속성을 ref로 주면 이 DOM의 객체 주소를 inputEl에 저장한다.
DOM 소개, mdn web docs
https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction
useRef, React
https://ko.legacy.reactjs.org/docs/hooks-reference.html#useref