-
-
Notifications
You must be signed in to change notification settings - Fork 139
Description
Hi, I am still getting this error in some circumstances.
react-plotly.js@2.4.0
plotly.js@1.54.6
I reported this error in the closed issue #52 two months ago. But I did not get any reaction, so I am opening a new issue.
I tried to debug my situation and come to finding that library is not checking if a component is mounted in promise handlers in updatePlotly function.
Short story
Hence, whenever the component mounts and in next moment it unmounts (before all promises in updatePlotly resolves), the syncWindowResize will call Plotly.Plots.resize with null (this.el) as an argument.
What happened in my situation in details (I've put some checkpoints in comments in bellow snippet):
updatePlotly(shouldInvokeResizeHandler, figureCallbackFunction, shouldAttachUpdateEvents) {
// updatePlotly: checkpoint 1
this.p = this.p
.then(() => {
if (!this.el) {
let error;
if (this.unmounting) {
error = new Error('Component is unmounting');
error.reason = 'unmounting';
} else {
error = new Error('Missing element reference');
}
throw error;
}
// updatePlotly: checkpoint 2
return Plotly.react(this.el, {
data: this.props.data,
layout: this.props.layout,
config: this.props.config,
frames: this.props.frames,
});
})
.then(() => this.syncWindowResize(shouldInvokeResizeHandler) // updatePlotly: checkpoint 3)
.then(this.syncEventHandlers)
.then(() => this.figureCallback(figureCallbackFunction))
.then(shouldAttachUpdateEvents ? this.attachUpdateEvents : () => {})
.catch(err => {
if (err.reason === 'unmounting') {
return;
}
console.error('Error while plotting:', err); // eslint-disable-line no-console
if (this.props.onError) {
this.props.onError(err);
}
});getRefsets ref correctlycomponentDidMountupdatePlotly- updatePlotly: checkpoint 1updatePlotly- updatePlotly: checkpoint 2componentWillUnmountgetRefunmounting sets ref tonull(see https://reactjs.org/docs/refs-and-the-dom.html#callback-refs)updatePlotly- updatePlotly: checkpoint 3syncWindowResizecalls Plotly.Plots.resize with argumentthis.el, which was set tonull(step 6) and that results inError while plotting: Error: DOM element provided is null or undefined.
Possible solution
Do not call things in promise then handler when unmounting:
// ...
.then(() => {
if(!this.unmounting) {
return this.syncWindowResize(shouldInvokeResizeHandler))
}
}
// ...Alternative solution
Do not use this.unmountig at all and implement solution with cancelable promises:
https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html