【问题标题】:React component did mount but stated unmounted actuallyReact 组件确实挂载了,但实际上声明为未挂载
【发布时间】:2020-09-25 06:59:39
【问题描述】:

我对 componentDidMount 和 componentWillUnmount 行为有一个奇怪的问题。当组件卸载时,由于来自名为 react-stockchart

的库的 HOC 的影响,然后再次重新安装

类似这样的东西: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,发现 Unmounted the MainChart --> Remount the 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,
                    plotData,
                    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 时,没问题,但是从另一个组件调用 using ref,它仍然没有更新 MainChart 组件的新状态。有什么方法可以刷新 ref 吗?

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

【问题讨论】:

  • 你为什么在 react 中使用 javascript...使用 react 方法
  • 对不起,我已经编辑了代码,我实际上绑定了那个函数,函数工作正常,问题是为什么它仍然卸载?你对此有什么想法吗?
  • 要重新安装的componentDidMountcomponentWillUnmount 组件在哪里?您能否提供ChartCanvas 的组件代码,以便我们可以通过 ref 看到正在执行的操作? sn-ps 非常脱节。是MainChart 组件的第三个sn-p 部分吗?
  • ChartCanvas 是库中的组件。 componentDidMountcomponentWillUnmountxAxisZoomMainChart 组件内。请注意,我使用 ref 从另一个组件调用了xAxisZoom
  • 类似:this.mainChartRef.xAxisZoom(args1, args2) 来自另一个组件,而不是 MainChart 本身

标签: reactjs charts react-lifecycle


【解决方案1】:

我找到了原因,在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 (
         ...
       )
 } 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    • 2016-05-22
    • 2017-08-12
    • 2021-05-26
    相关资源
    最近更新 更多