D3 and react

I know, there are various posts about how to integrate D3 into react components like this or this. If you try it naively you'll face the problem of having a new diagram for each state change and that's a bit odd. Otherwise the showed solutions in above mentioned posts will require much more time to add a short small little D3 diagram. Here's my solution which will get you a diagram controlled by D3 and updated on whatever your condition is. The really important part is to remove the whole svg item inside the given react item and re-add it. Not the most elegant way but hey: it works!

import React from "react";
import { Link } from 'react-router-dom';
import {connect} from 'react-redux';
import $ from "jquery";
import '../../ext/js/bootstrap';
import * as d3 from "d3";

class PriceGraphComponent extends React.Component {

    constructor(props) {
        this.svg = null;

    renderD3(item) {
        var data = item.prices;
        var mindate = data[0].seen,
            maxdate = data[data.length-1].seen;


        var margin = {top: 40, right: 40, bottom: 40, left: 40},
            width = 530 - margin.left - margin.right,
            height = 500 - - margin.bottom;

        var x = d3.scaleTime()
            .domain(d3.extent(data, function(d) {return new Date(d.seen)}))
            .range([0, width]);

        var y = d3.scaleLinear()
            .domain(d3.extent(data, function(d) {return d.price_per_unit}))
            .range([height, 0]);

        var line = d3.line()
            .defined(function(d) { return d; })
            .x(function(d) { return x(new Date(d.seen)); })
            .y(function(d) { return y(d.price_per_unit); });

        this.svg ="#chart").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + + margin.bottom)
            .attr("transform", "translate(" + margin.left + "," + + ")");

            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x).tickSize(0).tickFormat(() => {}));

            .attr("class", "axis axis--y")

            .attr("class", "line")
            .attr("d", line);

            .data(data.filter(function(d) { return d; }))
            .attr("class", "dot")
            .attr("cx", line.x())
            .attr("cy", line.y())
            .attr("r", 3.5);

    componentDidMount() {

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        if (this.props.item.loading == true && nextProps.item.loading == false && nextProps.item.error != true){
  "#chart > svg").remove();
        return false;

    render() {
        return (<div className="col-md-5 mb-4">
                    <div className="card shadow-nohover">
                        <div className="card-header">Horizontal Bar Chart</div>
                        <div className="card-body" id="chart"> </div>

function mapStateToProps(state){
    return {...state};

function matchDispatchToProps(dispatch){
    return {dispatch};

export default connect(mapStateToProps, matchDispatchToProps)(PriceGraphComponent);