-
-
Notifications
You must be signed in to change notification settings - Fork 137
Description
Hi, I am still getting this error in some circumstances.
[email protected]
[email protected]
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);
}
});
getRef
sets ref correctlycomponentDidMount
updatePlotly
- updatePlotly: checkpoint 1updatePlotly
- updatePlotly: checkpoint 2componentWillUnmount
getRef
unmounting sets ref tonull
(see https://reactjs.org/docs/refs-and-the-dom.html#callback-refs)updatePlotly
- updatePlotly: checkpoint 3syncWindowResize
calls 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