[React] useRef를 사용한 이유

허주환·2023년 1월 19일
0

React

목록 보기
2/2

Polymer -> React 리펙토링을 진행하면서 useRef를 사용한 경우를 정리해보려고 한다.

1, useRef

보통 useRef는 DOM Element에 접근하여 width, height, value 값 등을 컨트롤 할 수 있다.

Dom Element 접근

Canvas 관련 컴포넌트를 리엑트로 리펙토링하면서
<canvas> 엘리먼트를 접근해서 크기 변경, text, line, image를 그리도록 구현했다.

const App = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [ctx, setCtx] = useState<CanvasRenderingContext2D | null>(null);
  // ... 다른 상태 값
  
  useEffect(() => {
    if (!canvasImagesRef.current) return;
    const canvas = canvasImagesRef.current;
    setCtx(canvas.getContext("2d"));
  }, [canvasRef]);
  
  return (
    <>
      /* ... */
      <canvas
        ref={canvasRef}
        />
    </>
  );
}

다르게 사용한 경우

위 canvas 컴포넌트에서 Map 데이터 구조를 사용하는 로직이 있는데
이때 useState 훅으로 선언한 변수가 아닌 일반적으로 선언된 변수가
리랜더링 되면서 초기화 되어 로직에 영향을 주었다.
(undefined가 계속 발생해서 삽질을 많이 함...)

const App = () => {
  const map = new Map<string, any>(); // 이 부분 
  // ... 다른 상태 값
  
  // 임의로 데이터 주입
  useEffect(() => {
    map.set("key1", "abc");
  }, []);
  
  
  const fun1 = () => {
	const result = map.get("key1"); 
    console.log(`result: ${JSON.stringify(result, null, 2)}`);
  }

  // ...
  return (
    <>
      /* ... */
    </>
  );
}
  • useState로 할당된 상태가 변경되면
    • App 컴포넌트가 리랜더린 되면서 map 변수는 new Map<string, any>()로 계속 새롭게 생성되었다.
    • result: undefined

계속 리랜더링 되더라도 map 객체가 초기화가 되지 않도록 useRef로 값을 할당하였다.
useRef 값으로 선언된 상태(예제에서 map)가 변경 되더라도 화면은 리랜더링 되지 않는다.

const App = () => {
  const map = useRef<Map<string, any>>(new Map<string, any>()); // 이 부분 
  // ... 다른 상태 값
  
  // 임의로 데이터 주입
  useEffect(() => {
    map.set("key1", "abc");
  }, []);
  
  const fun1 = () => {
  	const result = map.current.get("key1"); 
    console.log(`result: ${JSON.stringify(result, null, 2)}`);
    // ...
  }

  // ...
  return (
    <>
      /* ... */
    </>
  );
}
  • useState로 할당된 상태가 변경되면
    • result: "abc"
  • DOM 접근 말고 다르게 useRef를 쓰는 경우
    • 초기화가 되면 안되는 일반 변수 (위 예제)
    • 리랜더링이 필요 없는 상태 값

2. Reference

profile
Junior BE Developer

0개의 댓글