[React] useRef - 변수 관리
[ 개념 ]
함수형 컴포넌트에서 useRef()를 호출하면 ref를 반환 해줍니다.
ref 객체는 언제든 지 수정 할 수 있습니다.
반환된 ref는 컴포넌트의 전 생의 주기를 통해 유지가 됩니다.
즉, 컴포넌트가 계속 리렌더링이 되어도 언마운드 되기 전까지는 값을 유지 합니다.
[ useRef는 언제 사용 될까요?? ]
첫번째 - 저장공간
ref는 state와 비슷하게 어떠한 값을 저장하는 저장 공간으로 사용됩니다.
함수형 컴포넌트는 함수이기 때문에 렌더링이 일어나면 함수를 다시 불러 옵니다.
그 때문에 안에 있는 변수들이나 함수들이 다시 불러와 져서 초기화가 됩니다.
두번째 - DOM 요소에 접근
ref를 통해 실제적으로 DOM 요소에 접근해서 여러가지 일을 할 수 있습니다.
예를 들어 input 태그를 누르지 않더라도 로그인 컴포넌트가 불러와 지면 focus를 설정 해주고 싶을 때 사용합니다.
(바닐라 JS의 document.querySelector()와 같은 역할을 합니다.)
[ 실습 ]
function App() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
// countRef => {current: 0} / countRef.current => 0
//
// state가 바뀌면 렌더링 O
const increaseCountState = () => {
setCount(count + 1);
};
// ref가 바뀌면 렌더링 X
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
};
return (
<div>
<p>State: {count}</p>
<p>CountRef: {countRef.current}</p>
<button onClick={increaseCountState}>State 올려</button>
<button onClick={increaseCountRef}>Ref 올려</button>
</div>
);
}
ref의 장점은?
: 자주 바뀌는 값을 state에 넣으면 값이 바뀔 때마다 계속 렌더링이 일어나기 때문에 성능에 안좋은 영향을 준다.
이때 ref를 사용하면 값이 바뀔 때마다 렌더링이 일어나지 않기 때문에 성능에 좋다.
function App() {
const [renderer, setRenderer] = useState(0);
const countRef = useRef(0);
let countVar = 0;
// ref가 바뀌면 렌더링 X
const increaseCountRef = () => {
countRef.current = countRef.current + 1;
console.log("ref: ", countRef.current);
};
// 변수가 바뀌면 렌더링 X
const increaseCountVar = () => {
countVar += 1;
console.log("var: ", countVar);
};
// 렌더링
const doRedering = () => {
setRenderer(renderer + 1);
};
return (
<div>
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={increaseCountRef}>Ref 올려</button>
<button onClick={increaseCountVar}>Var 올려</button>
<button onClick={doRedering}>렌더링</button>
</div>
);
}
컴포넌트 렌더링 → 컴포넌트 안에 변수, 함수가 새로고침 됨(ref는 새로고침 안됨) → ref 값은 그대로, var 값은 초기화
function App() {
const [count, setCount] = useState(1);
useEffect(() => {
setCount(count + 1)
});
return (
<div>
<p>{count}</p>
<button onClick={()=>{setCount(count + 1)}}>올려</button>
</div>
);
}
버튼 클릭 → setCount() 렌더링 → useEffect → setCount() 렌더링 → useEffect → .... 무한 루프
function App() {
const [count, setCount] = useState(1);
const renderCount = useRef(1);
useEffect(() => {
renderCount.current = renderCount.currnet + 1;
console.log("렌더링 수: ", renderCount.current);
});
return (
<div>
<p>{count}</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
올려
</button>
</div>
);
}
useRef를 사용하면 무한 렌더링의 늪에서 빠져 나올 수 있다👍