디바이스 크기에 따라 width 값을 결정하는 Hook
요구사항
텍스트 버블 차트를 프로젝트에서 활용하며, 프로젝트 마감 기한이 짧았기 때문에 내가 직접 구현하기보다 다른 사람이 d3를 통해 제작한 텍스트 버블 라이브러리를 사용했다.
하지만, 다른 사람이 제작한 라이브러리라서 나의 프로젝트와 맞지 않는 점이 있었는데, float된 요소가 많은 우리 프로젝트에서는 어느 정도의 반응형이 필요했지만, 이 라이브러리는 width 값을 프로퍼티로 받아 내부에서 svg를 조정하기 때문에 css로 반응형을 제어할 수 없었다.
이를 제어하기 위해서는 디바이스 크기에 따라서 width값을 js로 조작할 필요가 있었다.
해결과정
// hooks. js
export function useWindowSize() {
const [size, setSize] = useState(250);
useEffect(() => {
function handleResize() {
let width = 130 + window.innerWidth * 0.15;
width = Math.max(width, 250);
width = Math.min(width, 700);
setSize(width);
}
window.addEventListener("resize", handleResize);
handleResize();
return () => window.removeEventListener("resize", handleResize);
}, []);
return size;
}
// BubbleChartLayout.js
export default function BubbleChartLayout({ $type, isLoading, data }) {
const width = useWindowSize();
return (
<StyledBubbleChartLayout>
<div className="chart-box">
{data?.length ? (
<BubbleChart
graph={{
zoom: 1.1,
offsetX: 0,
offsetY: 0,
}}
width={width}
height={width}
padding={10}
showLegend={false} // optional value, pass false to disable the legend.
labelFont={{
family: "Pretendard",
size: 12,
color: "#fff",
weight: 600,
}}
data={data}
/>
) : null}
</div>
</StyledBubbleChartLayout>
이를 위해 useState, useEffect, window를 활용한 Hook을 제작하였다. useEffect를 활용하여 초기에 렌더링 될때, resize 이벤트를 등록해 주었다. resize가 발생할 때, 내가 설정한 함수를 통해서 디바이스 width값에 적절한 요소의 width 사이즈를 state로 관리하였으며, 이 값을 리턴하여 적절한 width 값을 지정해 주었다..
결과적으로 React는 state가 변경될 때마다 update가 일어나기 때문에, resize 이벤트를 통해 state를 업데이트해 주며 버블 차트가 마치 % css를 넣은 것처럼 디바이스 사이즈에 반응하도록 하였다.
결과화면
결과적으로 js 조작을 통해서 device의 width에 맞게 크기를 조작할 수 있는 차트를 제작할 수 있었다. 아래 이미지에서는 크기변화가 실감 나지 않지만, 더 큰 디바이스로 크기가 변경될 때 체감 될 수 있었다.
'개발' 카테고리의 다른 글
원할한 협업을 위한 노력 (2) 협업 환경 구성하기 (0) | 2023.07.04 |
---|---|
원할한 협업을 위한 노력 (1) 코드 리팩토링 (0) | 2023.07.03 |
Naver Cloud Plaform + Nginx + React 프론트 배포하기 (0) | 2023.05.28 |
[Error] React : received `true` for a non-boolean attribute 해결하기 (0) | 2023.05.22 |
[NEXT] Client Side에서는 API통신이 되는데 Server Side에서는 안됐는 이유 (0) | 2022.11.04 |