C3和React - DOMException

问题描述 投票:1回答:1

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

The problem

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

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

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

What I tried

我尝试使用setTimeout延迟图表附加,但奇怪的是我仍然得到相同的结果,即使在10秒延迟后。这让我相信这不是竞争条件,而是由其他因素造成的。也许C3读取DOM一次并且不响应变化?但这无法解释为什么它有时会起作用......

即使尝试从Chrome开发者控制台中按ID选择元素也无效。

enter image description here

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


export default Chart;
javascript html reactjs c3.js
1个回答
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,有时可能不生成(不确定uuid是如何工作的)

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

在你的HTML文档的顶部,并尝试。

也,

您在逻辑中使用了settimeout,并且在您使用this.Chart时使用了settimeout

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);
© www.soinside.com 2019 - 2024. All rights reserved.