본문 바로가기

React에서 D3.js를 사용할 때 어떻게 DOM 조작하는게 좋은가?

by mugglim 2026. 1. 17.

서론

처음으로 React에서 D3(D3.js)를 사용할 때 들었던 궁금점은 "D3와 React 중 어느 쪽에서 DOM을 제어할 것인가?"였습니다. React와 D3 모두 DOM을 변경할 수 있기 때문입니다.

이번 글에서는 React에서 D3를 사용하는 방식에 대해 이야기해보려고 합니다.

D3.js란 무엇인가?

D3Data-Driven Documents의 약자로 이름 그대로 데이터 시각화를 위한 라이브러리입니다. D3는 차트를 그리는 기능뿐만 아니라, 데이터 시각화를 위한 수학적인 계산을 처리하는 기능도 함께 제공합니다. (예시: d3-scale)

이제 React 환경에서 D3를 사용하는 방식을 알아봅시다.

React에서 D3 사용하기

D3로 DOM 조작하기

useRef로 빈 <svg> 컨테이너를 생성하고, useEffect 내부에서 D3에게 DOM 조작을 위임하는 것입니다. 이 방식은 React를 단순히 컨테이너 역할로만 사용합니다.

import { useRef, useEffect } from 'react';
import * as d3 from 'd3';

const Chart = ({ data }) => {
  const svgRef = useRef(null);

  useEffect(() => {
    const svg = d3.select(svgRef.current);

    if (!svg) {
      return;
    }

    svg.selectAll('*').remove();

    const lineGenerator = d3
      .line()
      .x((d) => d.x)
      .y((d) => d.y);

    svg.append('path')
      .datum(data)
      .attr('d', lineGenerator)
      .attr('stroke', 'steelblue')
      .attr('fill', 'none');

    svg
      .selectAll('circle')
      .data(data)
      .enter()
      .append('circle')
      .attr('cx', (d) => d.x)
      .attr('cy', (d) => d.y)
      .attr('r', 5);
  }, [data]);

  return <svg ref={svgRef} width={500} height={300} />;
};

export default Chart;

React로 DOM 조작하기

D3의 역할을 데이터의 계산으로 한정하고, React에게 DOM 조작을 위임하는 것입니다. D3는 DOM에 필요한 데이터를 계산하고, React가 DOM 조작의 역할을 가집니다.

import * as d3 from 'd3';

const Chart = ({ data }) => {
  const lineGenerator = d3
    .line()
    .x((d) => d.x)
    .y((d) => d.y);
  const pathData = lineGenerator(data);

  return (
    <svg width={500} height={300}>
      <path d={pathData} stroke="steelblue" fill="none" />
      {data.map((d, i) => (
        <circle key={i} cx={d.x} cy={d.y} r={5} />
      ))}
    </svg>
  );
};

export default Chart;

어떤 방식이 더 좋은가?

개인적으로 "React로 DOM을 조작하는 방식"의 경험은 괜찮았습니다. DOM이 그려지는 형태를 JSX로 확인 가능하고 D3와 React의 책임을 분리할 수 있는 장점이 있었습니다.

하지만 이 방식은 DOM 요소를 일일이 JSX로 관리해야 단점이 있습니다. 특히 프로젝트 규모가 커질수록 "어느 수준까지 공통 코드로 추상화할 것인가?"에 대한 커뮤니케이션 비용을 발생시킬 수 있습니다. 이 경우 recharts, visx 와 같은 라이브러리가 대안이 될 수 있습니다.

결론

서론에서 던졌던 "D3와 React 중 어느 쪽에서 DOM을 제어할 것인가?"라는 질문에 대한 답은 다음 두 가지 관점에서 찾을 수 있습니다.

첫째, 관심사의 분리입니다. 코드의 가독성, 예측 가능성을 고려하여 관심사를 분리하여 유지보수가 쉬운 구조에 대한 고민이 필요합니다.

둘째, 데이터와 DOM 간의 동기화 비용입니다. 비록 이번 글에서는 다루지 않았지만, 관리해야 할 DOM의 개수가 많은 상황이라면 두 방식에 대한 성능 벤치마크에 대한 고민이 필요합니다.

두 방식 중 정답은 없지만, React에서 D3를 사용하는데 도움이 되었길 바랍니다.

긴 글 읽어주셔서 감사합니다.

참고 자료

댓글