Ref
를 사용해야 하는 이유는 크게 두 가지로 나뉜다.
1. DOM
에 접근하여 HTML Element
를 핸들링 해야하는 경우
2. 상태 변화를 갖는 변수가 필요하지만, 화면이 리렌더링 되는 것을 원치않는 경우
DOM
에 접근하여 HTML Element
를 핸들링 해야하는 경우위 이미지는 Virtual DOM
을 정확하게 표현하는 자료라고 생각한다.
React
에서는 상태 변화를 감지하기 위해 DOM
을 그대로 복제한 가상 DOM
을 활용해 작업을 수행하는데, 이는 프레임워크 전반적으로 정해진 규칙 상 실제 DOM
에 접근해서는 안된다.
그렇다면, 내가 만든 HTML Element
는 어떻게 접근해야할까?
기능을 구현하다보면, HTML Element
에 focus
이벤트를 실행해야 하는 순간이라던가, 다양한 이유로 DOM
에 접근해야하는데, 이럴 때 사용하는 것이 바로 Ref
이다.
import { useRef } from 'react'
const inputRef = useRef()
//...
<input ref={inputRef} />
inputRef.current.focus() // DOM에 직접 접근하지 않았으므로, OK
Ref
와 State
의 가장 대표적인 차이점은, 값이 변경되었을 때 화면을 다시 그리냐 안 그리냐의 차이라고 볼 수 있다.
만약 setInterval
과 같은 비동기 함수를 State
를 활용해 작성한다면,
const [count, setCount] = useState(0)
let intervalAdd = null
function createInterval() {
intervalAdd = setInterval(() => setCount(count+1), 1000)
}
function removeInterval() {
clearInterval(intervalAdd)
}
위와 같은 구조로 할당되며, 이 때 interval의 주소값을 가진 intervalAdd
는 count
의 변화에 따라 화면이 다시 그려지며, 매번 초기화 되어 삭제 메시지가 닿지 못해 계속 쌓이기만 하는 것이다.
이 때 Ref
를 사용하면,
const [count, setCount] = useState(0);
const intervalAdd = useRef(null);
const startCounter = () => {
intervalAdd.current = setInterval(
() => setCount((count) => count + 1),
1000
);
};
const stopCounter = () => {
clearInterval(intervalAdd.current);
};
위와같이 리렌더링 됨에 따라 영향을 받지 않는 Ref
덕분에 문제가 생기지 않고 비동기 작업을 마무리 할 수 있다.