lifecarelog
프론트엔드

차트가 리사이즈를 안 따라올 때, window.resize 대신 ResizeObserver

사이드바를 접어도 차트가 그대로일 때, window.resize 대신 ResizeObserver로 컨테이너 크기를 직접 관찰해 해결하는 방법을 정리했어요.

4분 읽기

차트가 리사이즈를 안 따라올 때, window.resize 대신 ResizeObserver

사이드바를 접었는데 차트만 예전 크기 그대로 덩그러니 남아 있는 화면, 혹시 본 적 없나요? 창 크기를 살짝 흔들어 주면 그제야 차트가 맞춰지는 것도 같은 증상이에요.

혼자 운영하는 플랜씨(plan-c) 금융계산기에서 직접 겪은 문제였어요. 대출이자 계산 결과를 차트로 보여주는 화면인데, 결과 패널을 넓혀도 차트가 따라오지 않더라고요.

원인은 이벤트를 잘못된 곳에 붙인 것

많은 차트 코드가 window의 resize 이벤트에 갱신을 걸어둬요. 그런데 사이드바 접힘, 탭 전환, 분할 패널 드래그 같은 3가지 상황에서는 창 크기가 전혀 변하지 않아요. 변한 건 차트를 감싼 컨테이너뿐이라, 이벤트 자체가 오지 않는 거예요.

사이드바 접힘창 크기는 그대로window.resize 미발생차트 크기 유지

ResizeObserver로 컨테이너를 직접 관찰

해결책은 요소 자체의 크기 변화를 알려주는 ResizeObserver예요. 적용해 봤더니 코드는 10줄 안팎이면 충분했어요.

useEffect(function observeChartBox() {
  const box = boxRef.current;
  if (!box) return;
 
  const observer = new ResizeObserver((entries) => {
    const { width } = entries[0].contentRect;
    chartRef.current?.resize(width);
  });
 
  observer.observe(box);
  return () => observer.disconnect();
}, []);

이제 창이 아니라 차트 박스를 지켜보니, 패널을 어떻게 움직여도 차트가 바로 따라와요. 요즘 브라우저는 별도 폴리필 없이 그대로 쓸 수 있어요.

돌려 보니 만난 주의점 세 가지

첫 번째는 정리예요. 언마운트될 때 disconnect() 한 줄을 꼭 넣어 주세요. 위 코드처럼 useEffect의 정리 함수에 두면 끝나요.

두 번째는 콘솔의 loop 관련 경고예요. 콜백 안에서 다시 레이아웃을 건드리면 나타날 수 있는데, 테스트해 보면 requestAnimationFrame으로 한 프레임(약 16ms) 미뤄서 갱신하는 것만으로 사라져요.

세 번째는 호출 시점이에요. observe()를 등록하면 크기가 안 변해도 직후에 1회 콜백이 실행돼요. 초기 렌더 코드와 겹치면 차트가 두 번 그려질 수 있으니, 초기화와 리사이즈 갱신을 한 경로로 모아 두는 게 깔끔했어요.

  • 정리 함수에서 disconnect
  • 갱신은 한 프레임 지연
  • 등록 직후 1회 호출 유의

마무리

이벤트는 실제로 변하는 대상에 붙여야 해요. 창이 아니라 요소가 변하는 화면이라면, 관찰 대상도 요소여야 하고요. 반응형 레이아웃에서 차트가 굳어 있다면 window.resize부터 의심해 보세요.

#ResizeObserver#차트 리사이즈#React

라이프케어로그 서비스가 궁금하신가요?

AI 기반 건강·일정·재활 관리 앱을 직접 써보세요.

서비스 살펴보기

관련 글

댓글

아직 댓글이 없어요. 첫 댓글을 남겨주세요.