'D3.js ResizeObserver rendering issue. Axis not removed after resizing

Been experimenting with ResizeObserver in D3, the issue is that when the axis re-renders it leaves the old render behind, leaving a 'trace' of the previous axis.

The code is just a blank chart template, I used ResizeObserver to get the size of the dimensions of the div from the contentRect. It does seem to resize however.

Better explained in an image:

Before resizing the browser After resizing the browser

My code:

const useResizeObserver = (ref) => {
const [dimensions, setDimensions] = useState(null);

useEffect(() => {
    const observeTarget = ref.current;
    const resizeObserver = new ResizeObserver(entries => {
        entries.forEach(entry => {
            setDimensions(entry.contentRect);
        });
    });
    resizeObserver.observe(observeTarget);
    return () => {
        resizeObserver.unobserve(observeTarget);
    };
}, [ref]);

return dimensions;
};

export default function BarChart() {

const [data, setData] = useState([10]);
const svgRef = useRef();
const wrapperRef = useRef();
const dimensions = useResizeObserver(wrapperRef);

useEffect(() => {

    const margin = { top: 10, bottom: 10, right: 10, left: 10 };
    const svg = select(svgRef.current);

    if (!dimensions) return;

    // xAxis
    const xScale = scaleLinear()
        .domain([0, 10])
        .range([0, dimensions.width]);

    const xAxisFormat = number => format('')(number);

    const xAxis = axisBottom(xScale)
        .ticks(10)
        .tickFormat(xAxisFormat)
        .tickPadding(10);

    const xAxisG = svg.append('g')
        .call(xAxis)
        .attr('transform', `translate(0, ${height})`)

    svg
        .select('.xAxis')
        .call(xAxis)

    // yAxis
    const yScale = scaleLinear()
        .domain([0, 100])
        .range([height, 0]);

    const yAxisFormat = number => format('')(number);

    const yAxis = axisLeft(yScale)
        .ticks(10)
        .tickFormat(yAxisFormat)
        .tickPadding(10);

    const yAxisG = svg.append('g')
        .call(yAxis)

    svg
        .select('.xAxis')
        .call(xAxis)

},[data, dimensions]);

return (
    <React.Fragment>
    <div ref={wrapperRef}>
        <svg className="barChartSVG" ref={svgRef} width={width} height= {height} />
    </div>
    </React.Fragment>
);
}


Solution 1:[1]

Just add in the end of useEffect next lines:

return () => {
      svg.selectAll('*').remove()
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Vlad Novikov