如何在 React 中控制非 React 组件(BokehJS)?



背景故事
我想在我的 React 组件中包含 BokehJS 图。这样做的过程是呈现<div id="my_plot_id" className="bk-root"/>并调用window.Bokeh.embed.embed_item(plotData, 'my_plot_id'),将所需的HTML注入DOM中。

因为我想使用 React 组件的状态来控制 BokehJS 图(即用新生成的图数据替换图),所以我不想只在componentDidMount()中调用embed_item()。相反,我将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 阿拉伯数字

问题
因此,在正确检测到my_plot_id子项之前embed_item似乎执行了两次。

为什么会发生这种情况,我该如何解决?虽然三重渲染可能没有优化性能,但我相信我的组件应该能够根据需要(在合理范围内)重新渲染,而不会像这样出现视觉故障,所以我没有把注意力集中在防止重新渲染的方法上。

与 DOM 元素的交互不应该发生在render方法中。您应该使用生命周期方法componentDidMount在元素上启动库,使用componentDidUpdate根据 props 更新它并使用componentWillUnmount销毁它。

官方的 React 文档有一个使用 jQuery 的示例,它向您展示了如何处理其他 dom 库的要点。

开始时plotNode无法到达'my_plot_id'

您可以在开始时plotData不可用时呈现null

您可以使用componentDidUpdate().

在这种情况下,我会尝试shouldComponentUpdate()- 更新 DOM 节点并返回false以避免重新渲染。

最新更新