I have 2 files, bundle.jsx (contains React components) and app.js (contains JS functions, which includes Rickshaw classes for building graphs)
Within my react modules (bundle.jsx) within a class i render
<div id="chart_container" />
Within my js file i build on this div
var graph = new Rickshaw.Graph.Ajax( {
element: document.querySelector("#chart_container"), ...
}
The issue is when i load the 2 files, i expect the graph to be created whenever the div component is rendered by React. However this is not the case as my app.js file gets processed before my React component is rendered.
What is the best solution to this problem? Also am i approaching the problem correctly?
I have tried adding a setTimeout on app.js to load the functions after x seconds. This solves the issue and renders the graph, but is not fool-proof as sometimes the React component does not render in x seconds or renders much faster than x seconds.
Any help/suggestions?
You are looking for componentDidMount()
. This method is executed after the component has been rendered the first time, and therefore you can be sure that the chart container exists. Here is an example that illustrates this:
class Example extends React.Component {
componentDidMount() {
var graph = new Rickshaw.Graph( {
element: document.querySelector("#chart_container"),
width: 300,
height: 200,
series: [{
color: 'steelblue',
data: [
{ x: 0, y: 40 },
{ x: 1, y: 49 },
{ x: 2, y: 38 },
{ x: 3, y: 30 },
{ x: 4, y: 32 } ]
}]
});
graph.render();
}
render() {
return(
<div id="chart_container" />
);
}
}
ReactDOM.render(<Example/>, document.getElementById('View'));
<!-- React -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<!-- React DOM -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<!-- D3 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- Rickshaw -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/rickshaw/1.6.0/rickshaw.min.js"></script>
<div id="View"></div>