useRef와 useState로 변수 만들기
들어가며😃
useRef에 대한 포스팅을 초반에 한적이 있었는데, 그때는 DOM 속성을 조작하는 기능에 초점을 두었었다. 그래서 그런지 useRef에 변수를 저장할 수 있다는 법을 잠시 잊고있었고, 속성 조작하는 식으로 변수를 조작하려 삽질했다가 변수로 저장하는 법을 다시금 일깨우게되었다… 내 머릿속에 개념을 정리하고자 오늘은 useRef로 변수를 저장하는 법과 useState와의 차이점을 다뤄보려한다.
useRef
React 라이브러리에서 제공하는 훅(Hook) 중 하나로, 함수형 컴포넌트 내에서 변수를 만들고 관리하는 데 사용된다. 컴포넌트가 리렌더링되더라도 그 값을 유지하며, useState와는 다르게 리렌더링과 상관없이 값이 변경되더라도 컴포넌트의 리렌더링을 발생시키지 않는다.
1. 리렌더링 되어도 그 값을 유지한다고? 🤷🏻♀️
var 키워드로 변수를 선언해보자.
var countVar = 0;
const onClickVarBtn = () => {
countVar += 1;
console.log(`countVar 클릭 : ${countVar}`);
};
return (
/// 생략
{countVar}
<Button onClick={onClickVarBtn}>
var up!!
</Button>
)
위의 로직은 아래와 같다.
countVar
라는 변수를 선언하고 var up!! 버튼을 클릭하면 로그가 찍힌다.- 리렌더링을 발생시키면 변수가 다시 초기화된다.
- var up!! 버튼을 다시 누르면 초기화된 변수로 카운팅이 다시 된다.
변수를 키워드에 저장하면 리렌더링 시 값이 보존되지 않는 문제가 있다.
위의 문제를 해결하기 위해 나는 줄곧 state를 써왔고 리렌더링시에도 값을 보존할 수 있었다.
const [countState, setCountState] = useState(0);
const [render, setRender] = useState(0);
const onClickStateBtn = () => {
setCountState((prev) => prev + 1);
setRender((prev) => prev + 1);
};
useEffect(() => {
console.log(`countState 클릭 : ${countState}`);
}, [countState]);
return (
/// 생략
{countState}
<Button onClick={onClickStateBtn}>
state up!!</Button>
)
위에서 state를 변경하면 화면이 리렌더링이 되고, 물론 state에 저장되어있는 값과 상관없이 화면을 리렌더링 하더라도 값은 카운팅된 값 그대로 나타나며 이어서 계산된다.
그렇다면 이제 ref 를 통해 변수를 선언하면 어떻게 되는지 비교해보자.
const countRef = useRef(0);
const onClickRefBtn = () => {
countRef.current += 1;
console.log(`countRef 클릭 : ${countRef.current}`);
};
return (
/// 생략
{countRef.current}
<Button onClick={onClickRefBtn}>
Ref up!!</Button>
)
ref up!! 버튼을 누르면 카운팅 된 변수가 로그가 찍힌다. 하지만 좌측 화면에서 변수를 나타내는 값에서는 변화가 없다. 리렌더링 시키기 버튼을 누르면 이제껏 카운팅되었던 변수가 화면에 업데이트된다.
2. 리렌더링을 발생시키지 않는다고? 🤷🏻♀️
바로 위의 로직을 보면 알 수 있듯이, ref는 값에 변화가 있어도 state 와는 달리 리렌더링을 발생시키지 않는다. 그렇기 때문에 경우에 따라 리렌더링 발생을 원치 않을 때, 이전값과 현재값을 비교하고 싶을 때 등에서 ref로 변수를 쓸 수 있다. 물론 대부분의 경우 변화된 값을 화면에 바로 업데이트 해주어야하기 때문에 state 사용이 잦겠지만, state의 특성과 ref의 특성을 정확히 알고 있다면 원하는 경우에 원하는 메소드를 적절하게, 효율적으로 사용할 수 있을 것이다.
요즘 admin 페이지를 개발 중인데, 처음엔 state로 변수들을 관리하다가 ref식으로 변경되었다. 하지만 쿼리스트링에서 파라미터를 받아와 변수들에 바로 반영을 해주어야했기 때문에 ref 에서 다시 state로 변수를 관리하게 되었다는 사실…😵💫 하지만 덕분에 ref 를 사용해서 변수를 저장하는 법에 대해 재정리할 수 있는 시간을 마련하게 되었다. 사실 변수라하믄 무조건 state만 때려썼는데 이제는 둘을 생각할 수 있는 사람이 된것같다. 아주 뿌듯하다😎