[英]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
空值
00
22
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.