Backstory
I want to include a BokehJS plot in my React component. The process for this is to render <div id="my_plot_id" className="bk-root"/>
and call window.Bokeh.embed.embed_item(plotData, 'my_plot_id')
which injects needed HTML into the DOM.
Because I want to control the BokehJS plot using the React component's state (ie replace the plot with new generated plot data), I don't want to just call embed_item()
in componentDidMount()
. I've instead placed embed_item()
in render()
and added some code to remove child nodes of the container div prior to this call.
Problem
My React component renders 3 times on page load and although by the final render I have only one plot displayed, there is a brief moment (I think between the 2nd and 3rd/final render) where I see two plots.
Code
render()
{
let plotNode = document.getElementById('my_plot_id');
console.log(plotNode && plotNode.childElementCount);
while (plotNode && plotNode.firstChild) {
//remove any children
plotNode.removeChild(plotNode.firstChild);
}
const { plotData } = this.state;
window.Bokeh.embed.embed_item(plotData, 'my_plot_id');
return(
<div id="my_plot_id" className="bk-root"/>
)
}
In console I see:
null
0
2
Question
So it seems embed_item
executes twice before the my_plot_id
children are correctly detected.
Why is this happening and how can I resolve it? While the triple render may not be performance optimized I believe my component should be able to re-render as often as it needs to (within reason) without visual glitching like this, so I haven't focused my thought on ways to prevent re-rendering.
Interaction with DOM elements should never happen inside the render
method. You should initiate the library on the element using the lifecycle method componentDidMount
, update it based on props using componentDidUpdate
and destroy it using componentWillUnmount
.
The official React documentation has an example using jQuery which shows you the gist of how to handle other dom libraries.
At start plotNode
is unable to reach 'my_plot_id'
.
You can render null
at start, when plotData
is unavailable.
You can use componentDidUpdate()
.
In this case I would try shouldComponentUpdate()
- update DOM node and return false
to avoid rerendering.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.