I had a weird problem with componentDidMount and componentWillUnmount behavior. When the component unmount, and then remount again because of the effect of a HOC which come from a library called react-stockchart
Something like this: fitWidth(MyComponent)
. The behavior of unmount and remount again, whenever the width change is expected.
componentDidMount() {
this._isMounted = true;
document.addEventListener("keyup", this.onKeyPress);
document.addEventListener("touchstart", this.onTouchStart);
document.addEventListener("touchmove", this.onTouchMove);
document.addEventListener("touchend", this.onTouchEnd);
document.addEventListener("touchcancel", this.onTouchEnd);
window.addEventListener('resize', this.onResize)
console.log('Remount the MainChart');
}
componentWillUnmount() {
this._isMounted = false;
document.removeEventListener("keyup", this.onKeyPress);
document.removeEventListener("touchstart", this.onTouchStart);
document.removeEventListener("touchmove", this.onTouchMove);
document.removeEventListener("touchend", this.onTouchEnd);
document.removeEventListener("touchcancel", this.onTouchEnd);
console.log('Unmounted the MainChart')
}
I tried to console.log from componentDidMount and componentWillUnmount and see that Unmounted the MainChart --> Remount the MainChart log. But the problem is when I called a function inside this component that have setState statement from another component(using ref), it state that
Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
The code for that function inside class:
class MainChart extends React.Component {
constructor(props) {
super(props);
this.xAxisZoom = this.xAxisZoom.bind(this);
}
xAxisZoom(newDomain, callback)
{
// Copy from ChartCanvas.js
const { xScale, plotData, chartConfig } = this.canvas.calculateStateForDomain(newDomain);
this.canvas.clearThreeCanvas();
console.log(this._isMounted) //Always false after Remount the MainChart log.
if (this._isMounted) {
this.canvas.setState({
xScale,
plotData,
chartConfig,
}, callback);
}
}
}
export default fitWidth(MainChart);
The call like this: this.mainchartRef.xAxisZoom(args)
One more note: this.canvas
is a ref:
return (
<ChartCanvas ref={node => {if(node) this.canvas=node;}} width={width}
height={mainChartHeight} minPointsPerPxThreshold={0.02}
mouseMoveEvent={!simpleMode}
/>
Really confused even when the log from componentDidMount has been written, but after execute the function xAxisZoom, it state the component still was unmounted. Why the component seems not yet mounted?
One finding that I have made: When I called the xAxisZoom inside MainChart
component itself, it's ok, but calling using ref from another component, it still not yet update the new state of MainChart component. Is there any way to refresh the ref?
NOTE: All the snippets above are in MainChart
component
. Any idea would be very appreciated.