背景故事
我想在我的React组件中包含一个BokehJS图。此过程是呈现<div id="my_plot_id" className="bk-root"/>
并调用window.Bokeh.embed.embed_item(plotData, 'my_plot_id')
,这会将所需的HTML注入DOM。
因为我想使用React组件的状态来控制BokehJS图(即用新生成的图数据替换图),所以我不想只在embed_item()
中调用componentDidMount()
。我将embed_item()
放在render()
中,并在此调用之前添加了一些代码来删除容器div的子节点。
问题
我的React组件在页面加载时渲染3次,尽管到最后一次渲染,我只显示了一个图,但是有一小段时间(我认为在第二和第三/最终渲染之间),我可以看到两个图。
代码
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"/>
)
}
在控制台中,我看到:
空
0
2
问题
因此,在正确检测到embed_item
子级之前,似乎my_plot_id
执行了两次。
为什么会发生这种情况,我该如何解决?虽然三重渲染可能无法优化性能,但我认为我的组件应该能够(在合理的范围内)按需要进行多次重新渲染,而不会出现类似的视觉故障,因此我并未将思想集中在防止重新渲染上。渲染。
答案 0 :(得分:0)
与DOM元素的交互应该从不发生在render
方法内部。您应该使用生命周期方法componentDidMount
在元素上启动库,使用componentDidUpdate
根据道具更新它,并使用componentWillUnmount
销毁它。
official React documentation有一个使用jQuery的示例,向您展示了如何处理其他dom库的要点。
答案 1 :(得分:0)
开始时plotNode
无法到达'my_plot_id'
。
当null
不可用时,您可以在开始时渲染plotData
。
您可以使用componentDidUpdate()
。
在这种情况下,我将尝试shouldComponentUpdate()
-更新DOM节点并返回false
以避免重新呈现。