问题描述
我对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 (
...
)
}