[React] useRef - 변수 관리
본문 바로가기
프레임워크/React

[React] useRef - 변수 관리

by 은돌1113 2022. 1. 25.

  [ 개념 ]  

 

함수형 컴포넌트에서 useRef()를 호출하면 ref를 반환 해줍니다.

ref 객체는 언제든 지 수정 할 수 있습니다.

반환된 ref는 컴포넌트의 전 생의 주기를 통해 유지가 됩니다.

즉, 컴포넌트가 계속 리렌더링이 되어도 언마운드 되기 전까지는 값을 유지 합니다.

 

  [ useRef는 언제 사용 될까요?? ]  

 

첫번째 - 저장공간

ref는 state와 비슷하게 어떠한 값을 저장하는 저장 공간으로 사용됩니다.

ref의 특징

함수형 컴포넌트는 함수이기 때문에 렌더링이 일어나면 함수를 다시 불러 옵니다.

그 때문에 안에 있는 변수들이나 함수들이 다시 불러와 져서 초기화가 됩니다.

 

두번째 - 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를 사용하면 무한 렌더링의 늪에서 빠져 나올 수 있다👍

댓글