차트가 리사이즈를 안 따라올 때, window.resize 대신 ResizeObserver
사이드바를 접어도 차트가 그대로일 때, window.resize 대신 ResizeObserver로 컨테이너 크기를 직접 관찰해 해결하는 방법을 정리했어요.
차트가 리사이즈를 안 따라올 때, window.resize 대신 ResizeObserver
사이드바를 접었는데 차트만 예전 크기 그대로 덩그러니 남아 있는 화면, 혹시 본 적 없나요? 창 크기를 살짝 흔들어 주면 그제야 차트가 맞춰지는 것도 같은 증상이에요.
혼자 운영하는 플랜씨(plan-c) 금융계산기에서 직접 겪은 문제였어요. 대출이자 계산 결과를 차트로 보여주는 화면인데, 결과 패널을 넓혀도 차트가 따라오지 않더라고요.
원인은 이벤트를 잘못된 곳에 붙인 것
많은 차트 코드가 window의 resize 이벤트에 갱신을 걸어둬요. 그런데 사이드바 접힘, 탭 전환, 분할 패널 드래그 같은 3가지 상황에서는 창 크기가 전혀 변하지 않아요. 변한 건 차트를 감싼 컨테이너뿐이라, 이벤트 자체가 오지 않는 거예요.
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부터 의심해 보세요.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.