简体   繁体   English

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

[英]How to control a non-React component (BokehJS) in React?

Backstory 背景故事
I want to include a BokehJS plot in my React component. 我想在我的React组件中包含一个BokehJS图。 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. 这个过程是渲染<div id="my_plot_id" className="bk-root"/>并调用window.Bokeh.embed.embed_item(plotData, 'my_plot_id') ,它将所需的HTML注入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() . 因为我想使用React组件的状态控制BokehJS图(即用新生成的绘图数据替换图),我不想只在componentDidMount()调用embed_item() 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. 我改为在render()放置了embed_item() ,并在此调用之前添加了一些代码来删除容器div的子节点。

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. 我的React组件在页面加载时呈现3次,虽然在最终渲染中我只显示了一个图,但是有一个短暂的时刻(我想在第2和第3 /最终渲染之间),我看到两个图。

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 0
2 2

Question
So it seems embed_item executes twice before the my_plot_id children are correctly detected. 因此,在正确检测到my_plot_id子项之前,似乎embed_item执行了两次。

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. 与DOM元素的互动应该内部发生render方法。 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 . 你应该启动库中使用的生命周期方法的元素componentDidMount使用基于道具,更新componentDidUpdate和使用破坏它componentWillUnmount

The official React documentation has an example using jQuery which shows you the gist of how to handle other dom libraries. 官方的React文档有一个使用jQuery的例子,它向您展示了如何处理其他dom库的要点。

At start plotNode is unable to reach 'my_plot_id' . 在开始时, plotNode无法到达'my_plot_id'

You can render null at start, when plotData is unavailable. plotData不可用时,您可以在开始时渲染null

You can use componentDidUpdate() . 您可以使用componentDidUpdate()

In this case I would try shouldComponentUpdate() - update DOM node and return false to avoid rerendering. 在这种情况下,我会尝试shouldComponentUpdate() - 更新DOM节点并返回false以避免重新渲染。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM