들어가며😃


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>
  )

var


위의 로직은 아래와 같다.

  1. countVar 라는 변수를 선언하고 var up!! 버튼을 클릭하면 로그가 찍힌다.
  2. 리렌더링을 발생시키면 변수가 다시 초기화된다.
  3. 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를 변경하면 화면이 리렌더링이 되고, 물론 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


ref up!! 버튼을 누르면 카운팅 된 변수가 로그가 찍힌다. 하지만 좌측 화면에서 변수를 나타내는 값에서는 변화가 없다. 리렌더링 시키기 버튼을 누르면 이제껏 카운팅되었던 변수가 화면에 업데이트된다.


2. 리렌더링을 발생시키지 않는다고? 🤷🏻‍♀️

바로 위의 로직을 보면 알 수 있듯이, ref는 값에 변화가 있어도 state 와는 달리 리렌더링을 발생시키지 않는다. 그렇기 때문에 경우에 따라 리렌더링 발생을 원치 않을 때, 이전값과 현재값을 비교하고 싶을 때 등에서 ref로 변수를 쓸 수 있다. 물론 대부분의 경우 변화된 값을 화면에 바로 업데이트 해주어야하기 때문에 state 사용이 잦겠지만, state의 특성과 ref의 특성을 정확히 알고 있다면 원하는 경우에 원하는 메소드를 적절하게, 효율적으로 사용할 수 있을 것이다.





요즘 admin 페이지를 개발 중인데, 처음엔 state로 변수들을 관리하다가 ref식으로 변경되었다. 하지만 쿼리스트링에서 파라미터를 받아와 변수들에 바로 반영을 해주어야했기 때문에 ref 에서 다시 state로 변수를 관리하게 되었다는 사실…😵‍💫 하지만 덕분에 ref 를 사용해서 변수를 저장하는 법에 대해 재정리할 수 있는 시간을 마련하게 되었다. 사실 변수라하믄 무조건 state만 때려썼는데 이제는 둘을 생각할 수 있는 사람이 된것같다. 아주 뿌듯하다😎