1. useRef 개요


1-1) ref는 state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.

1-2) DOM 요소에 접근하기 위해 사용되기도 한다.

const UseRef = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(0); // 컴포넌트가 계속해서 렌더링 되어도 컴포넌트가 언마운트 되기 전 까지는 값을 유지한다.

  // 1. ref는 state와 비슷하게 어떤 값을 저장하는 저장공간으로 사용된다.
  // state의 변화 => 렌더링 => 컴포넌트 내부 변수들 초기화 (원하지 않는 렌더링 때문에 곤란해질 때 가 있다.)
  // Ref의 변화 => No렌더링 => 변수들의 값이 유지된다.
  // state의 변화 => 렌더링 => 그래도 Ref의 값은 유지된다.

  // 2. DOM 요소에 접근

  const increaseCountState = () => {
    setCount(count + 1); // state가 변경될 때마다 UseRef라는 컴포넌트가 다시 렌더링 된다.
  };
  const increaseCountRef = () => {
    countRef.current = countRef.current + 1; // ref는 수정되어도 컴포넌트가 렌더링 되지 않는다.
    console.log("Ref값 : ", countRef.current); // ref값은 올라가는게 보이지만 화면이 렌더링 되지 않기 때문에 화면에는 값이 그대로이다.
    // ref를 쓰는 이유 => state로 값을 변경하면 state가 바뀔 때마다 렌더링 되기 때문에 성능상 좋지 않다.
  };
  console.log("렌더링");

  return (
    <div>
      <h1>useRef1</h1>
      <button onClick={increaseCountState}>state +</button>
      <button onClick={increaseCountRef}>countRef +</button>
      <div>state : {count}</div>
      <div>useRef : {countRef.current}</div>
    </div>
  );
};
const UseRef2 = () => {
  const [render, setRender] = useState(0);
  const countRef = useRef(0); // ref는 렌더링이 되어도 값을 유지한다. (ref의 값은 컴포넌트의 전생애주기를 통해 유지가 된다.)
  let countVar = 0; // 렌더링될 때마다 (함수가 불릴 때 마다) 0으로 초기화 된다.

  const doRendering = () => {
    setRender(render + 1);
  };
  const increaseRef = () => {
    countRef.current = countRef.current + 1;
    console.log("Ref :", countRef.current);
  };

  const increaseVar = () => {
    countVar = countVar + 1;
    console.log("Var :", countVar);
  };

  const consoleRefVar = () => {
    console.log(`Ref : ${countRef.current} , var : ${countVar}`);
  };
  return (
    <div>
      <h1>useRef2</h1>
      <p>Ref : {countRef.current}</p>
      <p>var : {countVar}</p>
      <button onClick={doRendering}>Rendering Button</button>
      <button onClick={increaseRef}>Ref +</button>
      <button onClick={increaseVar}>Var +</button>
      <button onClick={consoleRefVar}>show in console</button>
    </div>
  );
const UseRef3 = () => {
  const [count, setCount] = useState(1);
  const refRenderCount = useRef(0);
  //   const [renderCount, setRenderCount] = useState(1);

  useEffect(() => {
    // console.log("렌더링");
    // setRenderCount(renderCount + 1); // count를 올리면 UseRef3이 다시 불리게 되고 useEffect가 불린다. useEffect안에도 state를 업데이트하는 카운트가 있어서 무한 반복된다.

    refRenderCount.current = refRenderCount.current + 1;
    console.log("렌더링 수 : ", refRenderCount.current);

    // useRef는 변화는 감지해야 하지만 그 변화가 렌더링을 발생시키면 안되는 어떤 값을 다룰 때 편리하다.
  });
  const increaseCount = () => {
    setCount(count + 1);
  };
  return (
    <div>
      <h1>useRef3</h1>
      <p>Count : {count}</p>
      <button onClick={increaseCount}>count+</button>
    </div>
  );
};

2. 기능구현