React组件确实已安装但实际已卸载

问题描述

我对componentDidMount和componentWillUnmount行为有一个奇怪的问题。卸载组件后,由于HOC的影响而重新安装了该组件,它来自名为 react-stockchart

的库

类似这样的内容:fitWidth(MyComponent)。每当需要更改宽度时,都会再次卸载并重新安装。

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')
    }

我尝试从componentDidMount和componentWillUnmount进行console.log,并看到卸载MainChart->重新装载MainChart 日志。 但是问题是,当我在该组件内部调用一个函数(该函数具有另一个组件的setState语句)(使用ref)时,它会指出

无法在已卸载的组件上调用setState(或forceUpdate)。这是空操作,但它表明应用程序中发生内存泄漏。要解决此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。

该函数在类内的代码:

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,chartConfig,},callback);
            }
        }
    }
 export default fitWidth(MainChart);

这样的呼叫:this.mainchartRef.xAxisZoom(args)

另外一个注释:this.canvas是参考:

return (

    <ChartCanvas ref={node => {if(node) this.canvas=node;}} width={width} 
        height={mainChartHeight} minPointsPerPxThreshold={0.02}
        mouseMoveEvent={!simpleMode}
    />

即使已经编写了componentDidMount的日志,但实际上还是很困惑,但是在执行功能 xAxisZoom 之后,它表明该组件仍处于卸载状态。为什么组件似乎尚未安装?

我发现的一个发现:当我在MainChart组件内部调用xAxisZoom时,没关系,但是使用来自另一个组件的ref调用时,它仍未更新MainChart组件的新状态。有什么方法可以刷新裁判吗?

注意:上面的所有摘录都在MainChart组件中 。任何想法将不胜感激。

解决方法

我找到了原因,在MainChart组件卸载并重新安装之后,我调用了另一个AnotherComponent组件,该组件保存着MainChart的引用(旧的引用MainChart,因此需要更新新的参考)。

因此,我在此处为解决此问题所做的工作是将一个函数从AnotherComponent传递到MainChart以便更新MainChart

class AnotherComponent extends React.Component {
   refreshMainChartRef = (ref) => {
      this.mainChartRef = ref
   }
   return (
     <MainChart refreshMainChartRef={refreshMainChartRef} />
   )
}

class MainChart extends React.Component {
   componentDidMount() {
        this._isMounted = true;
        // That line for update the ref for using from parent
        this.props.refreshMainChartRef(this); 
        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');
    }
       return (
         ...
       )
 } 

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...