Javascript 在什么情况下可以卸载根组件?
我有一个根组件,它初始化并托管整个应用程序,简化后看起来像Javascript 在什么情况下可以卸载根组件?,javascript,reactjs,Javascript,Reactjs,我有一个根组件,它初始化并托管整个应用程序,简化后看起来像 class App extends React.Component { componentDidMount() { // initialisation here } componentWillUnmount() { // I expect this to never happen } render() { // the whole app is
class App extends React.Component {
componentDidMount() {
// initialisation here
}
componentWillUnmount() {
// I expect this to never happen
}
render() {
// the whole app is rendered here
}
}
它在页面上的呈现非常简单(我只做了一次,该脚本在页面加载时运行,不会再次调用)
ReactDOM.render(,domeElement);
我最近发现,应用程序
的组件将卸载
有时(极少)会被调用
上次它发生在移动Chrome67上,但在桌面上也观察到了
我用一个虚拟的raven.captureMessage('application will unmount')捕获了那个事件
(其中,raven
是一个sentry客户端),所以目前我还没有更多的细节
但我完全感到惊讶:在什么情况下,react可以卸载根组件?没有JS触及react托管DOM,最后一次发生在我认识的一个人的手机上,它是一个普通的chrome浏览器,没有任何修改
我和那个人谈过——他们提到应用程序在视觉上看起来很正常(但由于明显的原因,它不能正常工作——因为我在那里取消了初始化)
另一个奇怪的时刻是,我还记录了该组件的componentDidMount
是否多次发生(通过模块范围的变量),并且它没有被调用
总结一下:调用了componentWillUnmount
,没有删除DOM节点,没有调用连续的componentDidMount
(这个序列听起来让我难以置信,但这就是我观察到的)
另一件重要的事情:对于最近的案例,它发生在chrome解除选项卡休眠之后(chrome在选项卡休眠或其他选项卡需要ram/cpu时将其置于休眠状态)
我在这里遗漏了什么吗?一种情况是使用
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);
constrootelement=document.getElementById('root');
const OtherComponent=()=>测试;
类应用程序扩展组件{
组件将卸载(){
log('will unmount');
}
handleRenderOtherComponent=()=>{
render(,rootElement);
};
render(){
返回(
除根
);
}
}
ReactDOM.render(并且您没有直接或通过某种包装库间接地调用ReactDOM.unmountComponentAtNode
任何地方?@djfdevgrep
forunmountComponentAtNode
显示它仅在react本身和reactstrap库中显示。在后一种情况下,它应用于modaldiv
。我确定不要直接调用它,ReactDOM.render(,domeElement);
实际上是我唯一可以引用App
的地方。@zerkms如果你找到了原因,我真的很想知道。我发现如果你在保存代码时创建一个codesandbox,componentWillUnmount()根组件的
正在被调用。但这可能是因为他们如何处理沙盒和模拟浏览器窗口的几个原因。@trixn因为它不可能重现-调试将花费相当长的时间:-D我将一次添加一件事到哨兵
日志消息以获得更深入的信息。是的,我将保持此帖子的更新ating@zerkms也许您可以抛出一个捕获到的错误来记录堆栈跟踪。这可能有助于理解错误调用方是谁。在我的情况下,我对这个想法投了赞成票,尽管我只渲染了一次(很抱歉在问题中没有提到它,现在已修复)这在react应用程序中呈现新的根组件是常见的吗?我还想知道何时调用根组件中的componentWillUnmountnormally@techguy2000大多数情况下,react应用程序是一个单页应用程序,只有一个根组件从未卸载。当父级不再呈现组件时,该组件将卸载。根组件没有可以卸载它的父组件。但是,由于呈现过程中出现未处理的错误,它可能会被卸载。没有任何限制可以阻止您在同一页上呈现多个根组件。这些都是相互相邻运行的独立应用程序。可能是其他wi上的一些小部件,如小组件se静态页面。
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);