在什么情况下可以卸载根组件?

时间:2018-07-31 20:17:04

标签: javascript reactjs

我有一个根组件,用于初始化和托管整个应用程序,并且在简化时看起来像

class App extends React.Component {
    componentDidMount() {
        // initialisation here
    }

    componentWillUnmount() {
        // I expect this to never happen
    }

    render() {
        // the whole app is rendered here
    }
}

它在页面上的渲染非常简单(我只做了一次,该脚本在页面加载时运行,并且再也不会被调用)

ReactDOM.render(<App />, domElement);

我最近发现的是,有时(非常罕见)App的{​​{1}}被调用。

上次它发生在移动Chrome 67上,但也出现在台式机上。

我用虚拟componentWillUnmount(其中raven.captureMessage('application will unmount');是哨兵客户)捕获了该事件,所以目前我没有更多细节。

但令我感到惊讶的是:在什么情况下根组件可以通过反应来卸载?没有JS接触过反应管理的DOM,最后一次发生在我认识的人的电话上,这是一个常规的Chrome浏览器,没有进行任何修改。

我和那个人交谈-他们提到该应用程序在外观上看起来很正常(但是由于明显的原因,它无法正常运行-因为我在这里取消了初始化工作)。

另一个奇怪的时刻是,我也记录了raven是否针对该组件发生了多次(通过模块作用域变量),并且没有被调用。

因此,总结一下:调用了componentDidMount,尚未删除DOM节点,未调用了连续的componentWillUnmount(此顺序听起来令人难以置信,但这就是我观察到的)。 / p>

另一件事:在最新情况下,它恰好在chrome取消休眠标签页之后发生(chrome在休眠状态下或其他标签页需要ram / cpu时,该标签页处于休眠状态)。

我在这里想念东西吗?

1 个答案:

答案 0 :(得分:1)

一种情况是,您使用ReactDOM将另一个组件渲染到根容器中:

const rootElement = document.getElementById('root');
const OtherComponent = () => <p>test</p>;

class App extends Component {    
    componentWillUnmount() {
        console.log('will unmount');
    }

    handleRenderOtherComponent = () => {
        ReactDOM.render(<OtherComponent />, rootElement);
    };

    render() {
        return (
            <button onClick={this.handleRenderOtherComponent}>
                remove root
            </button>
        );
    }
}

ReactDOM.render(<App />, rootElement);

Edit 1vp8o058p3