在componentDidUpdate中,refs未定义

时间:2016-08-09 10:44:15

标签: reactjs html5-canvas

我想在我的网站上使用Chart.js。正如你可以看到标题,我使用React.js。要使用Chart.js,我需要画布和上下文,如下所示:

let context = document.getElementById('canvas').getContext('2d');
let chart = new Chart(context, ...);

所以我设计了这样的组件:

export function updateChart() {
    let context = this.refs.chart.getContext('2d');
    let chart = new Chart(context ,... );
    ...
}

export default class GraphChart extends React.Component {
    constructor() {
        super();
        updateChart = updateChart.bind(this);
    }
    componentDidMount() {
        updateChart();
    }
    render() {
        return <canvas ref="chart" className="chart"></canvas>;
    }
}

如你所见,我导出了两件事,更新图表函数和GraphChart类。两者都将在父组件中使用,如下所示:

import { updateChart } from './GraphChart';
import GraphChart from './GraphChart';

class Graph extends React.Component {
    ...
    someKindOfAction() {
        // update chart from here!
        updateChart();
    }
    render() {
        return (
            <div>
                <SomeOtherComponents />
                <GraphChart />
            </div>
        );
    }
}

然后使用导出的updateChart函数直接更新图表的父类。它工作,但只是第一次。卸载并挂载GraphChart组件后,它的引用只是空的。

为什么refs是空的?如果我做错了,我如何获得画布上下文来初始化Chart.js?

1 个答案:

答案 0 :(得分:1)

对象refs未定义,因为this不是您认为的那样。尝试记录它。

您导出的功能未绑定到组件的this。或者它可能是,但是最后创建的组件实例。你永远无法确定是挂载的实例。即使你是,你也不能同时使用多个实例。所以,我完全不理会这种方法。

除此之外,提供改变某个组件状态的功能与React试图完成的功能正好相反。最基本的想法是组件应该知道给自己赋予一些属性。

您尝试解决的问题在于Canvas API的本质,它是程序性的。您的目标是弥合声明(React)和程序(Canvas)代码之间的差距。

有些库正是如此。你试过react-chartjs吗? https://github.com/reactjs/react-chartjs

无论如何,如果你想知道你应该如何实现它的“反应方式”,关键是声明你的组件处理的属性(不一定,但最好),然后使用组件生命周期方法(例如{ {1}}和其他人)检测属性何时更改并相应地执行操作(对画布执行更改)。

希望这有帮助!祝你好运!