리액트를 사용하기 전까지 우리는 특정 태그에 접근할 때 document.getElementById()
를 사용했다.
하지만, 리액트는 실제 DOM이 아닌 virtual DOM(가상돔)을 다루기 때문에 document.getElementById()
으로 접근했을 때 문제가 생긴다.
리액트에서 저장공간이라 하면 보통 state가 떠오른다. 하지만 state는 값이 변할 때마다 리렌더링이 되면서 컴포넌트 내부 변수들이 초기화가 된다. 즉, 해당 컴포넌트 함수의 변수들이 모두 초기화되고 모든 함수 로직이 다시 실행되는 것을 의미한다.
❗️ 결론은 불필요한 렌더링을 막기 위해 useRef를 사용한다
또한 컴포넌트가 아무리 렌더링 되어도 ref안에 저장된 값은 변화되지 않고 그대로 유지된다. 변경 시 렌더링을 원하지 않는 값을 다룰 때 편하다.
대표적으로 input 요소를 클릭하지 않고 포커스를 주고 싶을 때 사용
예를 들어, 로그인 화면에 id 칸을 클릭하지 않아도 자동으로 포커스 된다면 편리할 수 있다.
예를 들어 , 카운터 값을 0으로 초기화 할 필요가 있을 때
setInterval 이나 setTimeout같은 함수는 clear를 시키지 않으면 메모리 소모량이 크다.
예제 )
import { useState, useEffect } from "react";
function ManualCounter() {
const [count, setCount] = useState(0);
const intervalId = useRef(null);
console.log(`랜더링... count: ${count}`);
const startCounter = () => {
intervalId.current = setInterval(
() => setCount((count) => count + 1),
1000
);
console.log(`시작... intervalId: ${intervalId.current}`);
};
const stopCounter = () => {
clearInterval(intervalId.current);
console.log(`정지... intervalId: ${intervalId.current}`);
};
return (
<>
<p>자동 카운트: {count}</p>
<button onClick={startCounter}>시작</button>
<button onClick={stopCounter}>정지</button>
</>
);
}
useRef
함수는 current
속성을 가지고 있는 객체를 반환하는데 인자로 넘어온 초기값을 current
속성에 할당한다.
시작버튼을 누르면 새로운 intervalId 가 생성되고, 정지 버튼을 누르면 기존 intervalId가 정리되는 걸 볼 수 있다.
실행화면 )
참고 블로그 + 나중에 참고할 블로그
useRef 200% 활용하기: https://velog.io/@juno7803/React-useRef-200-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0
useRef 사용법과 예제: https://itprogramming119.tistory.com/entry/React-useRef-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C
useRef 사용법 : https://www.daleseo.com/react-hooks-use-ref/