이번 포스팅은 리액트의 함수형컴포넌트에서의 UseRef 를 다루어보려 합니다.
현재 프론트엔드를 공부중이고 자바스크립트와 리액트를 병행하여 시작하고 있는데요, 아직 주니어도 못되는 수준이라서 틀린 부분에 대해서는 댓글로 알려주시면 감사하겠습니다^^
useRef 는 프로퍼티에 변경 가능한 값을 담고있는 '상자' 같은 녀석입니다.
useRef 는 생성되면 current 라는 객체를 생성하고, 만들어진 current 객체는 다른 렌더링이 발생해도 변경되지않고 고유한객체를 유지합니다.
렌더링에 영향을 받지않고, 영향을 끼치지도 않습니다.
ref의 변경은 감지되지도 않으니 useEffect의 디펜던시로도 사용할 수 없습니다. ( 아직 useEffect를 잘 모르니 나중에 알아보겠습니다 )
컴포넌트가 평가될 때 만들어질까요??
컴포넌트가 평가되고 실행되는 일련의 과정을 거치는 중 current 객체는 null로 평가됩니다.
useRef를 사용하여 DOM에 접근할 때는 컴포넌트가 마운트 된 이후에 사용해야 null 에러를 피할 수 있습니다.
변수관리를 하기위해 사용할때에는 문제가 되지 않습니다.
useRef로 DOM에 접근할 때는 컴포넌트가 렌더링된 후에 사용해야 안전합니다. UseEffect 사용을 권장합니다.
useEffect는 컴포넌트가 렌더링되는 시점을 분기처리하여 특정 작업을 실행할 수 있도록 해주는 녀석입니다.
- 컴포넌트가 마운트 됐을 때
- 컴포넌트가 언마운트 됐을 때
- 컴포넌트가 업데이트 됐을 때
- 등등
useRef 를 사용하는 경우는 아래와 같습니다.
- 특정 엘리먼트의 위치,크기를 알아낼 때
- 스크롤바의 위치를 가져오거나 설정할 때
- focus를 설정해야 할 때
- Video.js 등 HTML의 비디오관련 라이브러리를 사용할 때
- D3, Chart.js 등 그래프관련 라이브러리를 사용할 때 ( 특정 DOM에 라이브러리를 설정해야 함 )
UseRef는 내가 보관하고싶은 유실되지 않았으면 하는 데이터를 보관할 때 사용하는게 핵심입니다.( 렌더링에 관여받고싶지 않은 데이터 ) 위에 말한것은 몇가지의 예시이고 정해진건 없습니다.
UseRef는 두가지의 특징을 가지고있습니다.
DOM 접근
const Test = () => {
const accessDom = useRef(null) //null로 초기화하지 않고 사용하면 안되던데 왜그런가요..?
useEffect(() => { 수행할 함수 });
return (
<div ref={accessDom}> HTML 엘리먼트 속성으로 UseRef 선언한 변수를 넣습니다. </div>
);
};
export default Test;
변수관리
useRef로 선언된 변수가 변하지않고 유지되는지 정확히 확인하기위해선 화면의 리렌더링이 필요합니다.
const Test = () => {
const accessDom = useRef(0) //null로 초기화하지 않고 사용하면 안되던데 왜그런가요..?
console.log("렌더링 후 Ref :", countRef.current); //State, Props에 의해 리렌더링 됐을 때 변경이 반영됩니다.
useEffect(() => { 수행할 함수 });
const increaseRef = () => {
countRef.current = countRef.current + 1;
console.log("Ref 증가 : " + countRef.current);
};
return (
<button onClick={increaseRef}>Ref Up!</button> //버튼 클릭시 Ref 값 증가
);
};
export default Test;
좋은 글 잘 보고 갑니다 :)