0


背景故事我想在我的 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

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

4

2 回答 2

0

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

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

于 2019-05-03T15:56:19.650 回答
0

一开始plotNode是无法到达的'my_plot_id'

null您可以在开始时渲染,当plotData不可用时。

您可以使用componentDidUpdate().

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

于 2019-05-03T15:58:19.000 回答