C3和React-DOMException

时间:2019-03-05 05:03:40

标签: javascript html reactjs c3.js

我正在尝试使用C3在我的React项目中绘制图表。

问题

我要做的是动态生成一个id(UUID),并将其附加到图表组件中的div上。然后,在组件以componentDidMount呈现之后,我将调用一些代码。这是一种常见的模式,我在其他项目中也看到过。

起初,一切似乎都很好。但是,在反复刷新页面后,有时无法生成图表。我得到的错误是:

DOMException: Failed to execute 'querySelector' on 'Document': '#a-really-long-id' is not a valid selector.

我尝试过的

我尝试使用setTimeout来延迟图表的添加时间,但是奇怪的是,即使延迟了10秒,我仍然得到相同的结果。这使我相信这不是比赛条件,是由其他原因引起的。也许C3读取DOM一次并且不响应更改?但这并不能解释为什么有时...

即使尝试从Chrome开发者控制台中按ID选择元素,也行不通。

enter image description here

代码

这是我的完整组件代码:

// 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 (
            <div id={this.id} className="chart"></div>
        );
    }
}


export default Chart;

1 个答案:

答案 0 :(得分:1)

可以将其添加为注释,但由于注释很大,因此将其添加为答案。

您是否使用html4 / html5语义?

按照HTML4(https://www.w3.org/TR/html401/types.html

  

ID和NAME令牌必须以字母([A-Za-z])开头,并且可以是   后跟任意数量的字母,数字([0-9]),连字符(“-”),   下划线(“ _”),冒号(“:”)和句点(“。”)。

按照HTML5(https://www.w3.org/TR/html5/dom.html

  

在HTML元素上指定时,id属性值必须唯一   在元素树的所有ID中,并且必须至少包含   一个字符。该值不得包含任何空格字符。

您的uuid有时可能会生成一个有效的ID,有时可能会生成一个有效的ID(不确定uuid的工作方式)

如果您不使用HTML5语义,则只需添加<!DOCTYPE html>

在HTML文档顶部的

并尝试一下。

您在逻辑中使用了settimeout,并在其中使用了this。图

this,现在将引用settimeout而不是类。

您可以尝试更改

setTimeout(function() {
        this.chart.load({
            columns: [
                ['Male', data.male],
                ['Female', data.female],
                ['Brand', data.brand]
            ]
        });
    }, 500);

  setTimeout( () => {
        this.chart.load({
            columns: [
                ['Male', data.male],
                ['Female', data.female],
                ['Brand', data.brand]
            ]
        });
    }, 500);