so let try something else, this is our code now:
```
import React, { useRef, useEffect, memo } from 'react';
import * as d3 from 'd3';

interface LineChartProps {
  width: number;
  height: number;
  dataSets: Array<{ name: string; data: Array<{ x: number; y: number }> }>;
}

const LineChart: React.FC<LineChartProps> = memo(({ width, height, dataSets }) => {
  const chartRef = useRef<SVGSVGElement | null>(null);
  const zoomTransformRef = useRef<d3.ZoomTransform>(d3.zoomIdentity);
console.log('re-render')
  useEffect(() => {
    if (!chartRef.current) return;

    const margin = { top: 20, right: 30, bottom: 50, left: 50 };
    const chartWidth = width - margin.left - margin.right;
    const chartHeight = height - margin.top - margin.bottom;

    const svg = d3.select(chartRef.current);
    svg.selectAll("*").remove();

    const defs = svg.append('defs');
    defs.append('clipPath')
      .attr('id', 'chartAreaClip')
      .append('rect')
      .attr('width', chartWidth)
      .attr('height', chartHeight);

    const g = svg.append('g')
      .attr('transform', `translate(${margin.left},${margin.top})`);

    const xScale = d3.scaleLinear()
      .domain([0, Math.max(...dataSets.flatMap(dataset => dataset.data.map(d => d.x))) || 1])
      .range([0, chartWidth]);

    const yScale = d3.scaleLinear()
      .domain([0, Math.max(...dataSets.flatMap(dataset => dataset.data.map(d => d.y))) || 1])
      .range([chartHeight, 0]);

    const xAxis = d3.axisBottom(xScale).ticks(10);
    const yAxis = d3.axisLeft(yScale).ticks(10);

    const xAxisGroup = g.append('g')
      .attr('class', 'x-axis')
      .attr('transform', `translate(0,${chartHeight})`)
      .call(xAxis);

    const yAxisGroup = g.append('g')
      .attr('class', 'y-axis')
      .call(yAxis);

    const xGridGroup = g.append('g')
      .attr('class', 'x-grid')
      .attr('transform', `translate(0,${chartHeight})`);

    const yGridGroup = g.append('g')
      .attr('class', 'y-grid');

    const chartArea = g.append('g')
      .attr('clip-path', 'url(#chartAreaClip)');

    const colorScale = d3.scaleOrdinal<number, string>(d3.schemeCategory10);

    const updateChart = () => {
      const transformedX = zoomTransformRef.current.rescaleX(xScale);
      const transformedY = zoomTransformRef.current.rescaleY(yScale);

      chartArea.selectAll('.line')
        .data(dataSets)
        .join('path')
        .attr('class', 'line')
        .attr('fill', 'none')
        .attr('stroke', (d, i) => colorScale(i))
        .attr('stroke-width', 2)
        .attr('d', d => d3.line<{ x: number; y: number }>()
          .x(d => transformedX(d.x))
          .y(d => transformedY(d.y))(d.data) || '');

      xGridGroup.call(
        d3.axisBottom(transformedX)
          .tickSize(-chartHeight)
          .tickFormat(() => '') as any
      ).selectAll('line')
      .style('stroke', '#e0e0e0')

      yGridGroup.call(
        d3.axisLeft(transformedY)
          .tickSize(-chartWidth)
          .tickFormat(() => '') as any
      ).selectAll('line')
      .style('stroke', '#e0e0e0')
    };

    const zoom = d3.zoom<SVGSVGElement, unknown>()
      .scaleExtent([0.5, 10])
      .on('zoom', (event) => {
        zoomTransformRef.current = event.transform;
        updateChart();
      });

    svg.call(zoom);

    updateChart();
  }, [dataSets, width, height]);

  return <svg ref={chartRef} width={width} height={height}></svg>;
});

export default LineChart;
```
let try trun this component to a class component and avoid re-rendering when data is update or change