title: C3 and React - DOMException
body: <p>I'm trying to use C3 to render a chart in my React project. </p>
  
  <h1>The problem</h1>
  
  <p>What I do is dynamically generate an id (UUID) and attach it to a <code>div</code> in my chart component. I then call some code after the component has rendered in <code>componentDidMount</code>. This is a common pattern, I have seen it in other projects.</p>
  
  <p>At first, everything seemed fine. However, after repeatedly refreshing the page, sometimes the chart generation does not work. The error I get is:</p>
  
  <pre><code>DOMException: Failed to execute 'querySelector' on 'Document': '#a-really-long-id' is not a valid selector.
  </code></pre>
  
  <h1>What I tried</h1>
  
  <p>I tried using <code>setTimeout</code> to delay when the chart was attached, but curiously I still got the same result, even after a 10 second delay. This leads me to believe that this is not a race condition, and caused by something else. Maybe C3 reads the DOM once and does not respond to changes? But that would not explain why it works <em>sometimes...</em></p>
  
  <p>Even trying to select the element by id from the Chrome developer console did not work.</p>
  
  <p><a href="https://i.stack.imgur.com/3nRba.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3nRba.png" alt="enter image description here"></a></p>
  
  <h1>Code</h1>
  
  <p>Here is my full component code:</p>
  
  <pre><code>// assets/js/index.jsx
  import React from 'react';
  import uuid from 'uuid/v4';
  import c3 from 'c3';
  
  
  class Chart extends React.Component {
      constructor(props) {
          super(props);
  
          this.id = uuid();
          this._update = this._update.bind(this);
      }
  
      _update() {
          const data = this.props.data;
          this.chart = c3.generate({
              bindto: `#${this.id}`,
              data: {
                  columns: [
                      ['Male', 0],
                      ['Female', 0],
                      ['Brand', 0]
                  ],
                  type: 'bar',
                  colors: {
                      Male: '#0066CC',
                      Female: '#FF6666',
                      Brand: '#808080'
                  },
                  groups: [
                      ['Male', 'Female', 'Brand']
                  ],
                  order: null
              },
              bar: {
                  width: {
                      ratio: 0.3
                  }
              },
              transition: {
                  duration: 500
              },
              tooltip: {
                  show: false
              },
              axis: {
                  x: { show: false },
                  y: { show: false },
              },
              size: { width: 220, height: 320 },
              grid: {
                  x: { show: false }
              },
              legend: {
                  show: false
              }
          });
  
          setTimeout(function() {
              this.chart.load({
                  columns: [
                      ['Male', data.male],
                      ['Female', data.female],
                      ['Brand', data.brand]
                  ]
              });
          }, 500);
      }
  
      componentDidMount() {
          this._update();
      }
  
      render() {
          return (
              &lt;div id={this.id} className="chart"&gt;&lt;/div&gt;
          );
      }
  }
  
  
  export default Chart;
  </code></pre>