Reactjs 刷新当前页面时未调用componentWillUnmount()

Reactjs 刷新当前页面时未调用componentWillUnmount(),reactjs,Reactjs,在刷新当前页面(以及随后的组件)时,componentDidMount()方法中的代码没有正确启动,我遇到了这个问题。然而,只要通过点击链接在我的网站上导航和路由,它就可以很好地工作。是否刷新当前页面?不可能 我发现问题在于当我刷新页面时,componentWillUnmount()不会触发,并触发精细单击链接和浏览我的网站/应用程序 触发componentWillUnmount()对于我的应用程序至关重要,因为我在componentDidMount()方法中加载和处理的数据对于向用户显示信息非

在刷新当前页面(以及随后的组件)时,
componentDidMount()
方法中的代码没有正确启动,我遇到了这个问题。然而,只要通过点击链接在我的网站上导航和路由,它就可以很好地工作。是否刷新当前页面?不可能

我发现问题在于当我刷新页面时,
componentWillUnmount()
不会触发,并触发精细单击链接和浏览我的网站/应用程序

触发
componentWillUnmount()
对于我的应用程序至关重要,因为我在
componentDidMount()
方法中加载和处理的数据对于向用户显示信息非常重要

我需要在刷新页面时调用
componentWillUnmount()
,因为在我的
componentWillMount()
函数(每次刷新后需要重新呈现)中,我执行一些简单的筛选,并将该变量存储在状态值中,它需要出现在
logos
状态变量中,以便组件的其余部分工作。这不会在组件生命周期的任何时候更改或接收新值

componentWillMount(){
  if(dataReady.get(true)){
    let logos = this.props.questions[0].data.logos.length > 0 ? this.props.questions[0].data.logos.filter((item) => {
      if(item.logo === true && item.location !== ""){
        return item;
      }
    }) : [];
    this.setState({logos: logos});
  }
};
悬崖:

  • 我在
    componentWillMount()
    方法中进行DB过滤
  • 刷新后是否需要将其显示在组件中
  • 但是我有一个问题,
    组件willunmount()
    在刷新页面时不会触发
  • 需要帮助吗

当页面刷新时,react无法正常卸载组件。使用事件设置刷新处理程序(阅读代码中的注释):

使用WindowUnloadeEffect挂钩

我已根据以下内容将代码提取到一个可重用的钩子中:

//钩子
const{useffect,useRef,useState}=React
const useWindowUnloadeEffect=(处理程序,callOnCleanup)=>{
const cb=useRef()
cb.current=handler
useffect(()=>{
常量处理程序=()=>cb.current()
addEventListener('beforeunload',handler)
return()=>{
if(callOnCleanup)处理程序()
removeEventListener('beforeunload',handler)
}
},[cb])
}
//用法示例
常量Child=()=>{
UseWindowUnloadeEffect(()=>console.log('unloaded'),true)
返回示例
}
常量演示=()=>{
const[show,changeShow]=useState(true)
返回(
changeShow(!show)}>{show?'hide':'show'}
{show?:null}
)
}
ReactDOM.render(
,
根
)

我看到这个问题有上千个视图,所以我将解释我是如何解决这个问题的:

为了解决这个特殊的问题,最明智的方法是创建一个加载订阅或数据库的上层组件,以便在将所需数据传递给子组件之前加载它,这样就完全不需要使用
componentWillMount()
。此外,您可以在上层组件中进行计算,并将它们作为道具传递给接收组件

例如:

class UpperLevelComponent extends React.Component {

render() {
if(this.props.isReady) {
return(<ChildComponent {...props}/>)
}
}
}

export default createContainer(() => {
const data = Meteor.subscribe("myData");
const isReady = data.ready();

return {
isReady,
data: MyData.find.fetch()
}
})
类UpperLevelComponent扩展了React.Component{
render(){
如果(本道具已准备就绪){
返回()
}
}
}
导出默认createContainer(()=>{
常量数据=Meteor.subscribe(“myData”);
const isReady=data.ready();
返回{
我已经准备好了,
数据:MyData.find.fetch()
}
})

在上面的示例中,我使用Meteor的reactive容器获取MongoDB数据,并等待它完全完成订阅,然后再渲染子组件,并传递我想要的任何道具。如果将所有数据加载到更高级别的组件中,则不必依赖于每次刷新后触发的
componentWillMount()
方法。数据将在上层组件中准备好,因此您可以在子组件中随意使用它。

我也遇到了这个问题,并意识到我需要确保至少有2个组件将始终正常卸载。所以我最后做了一个高阶组件,确保包装的组件总是卸载

import React,{Component}来自“React”
//此高阶组件将确保包装的组件
//将永远被卸载,即使反应没有时间
//调用componentWillUnmount函数
使用GracefulUnmount导出默认函数(WrappedComponent){
返回类扩展组件{
建造师(道具){
超级(道具);
this.state={mounted:false};
this.componentGracefulUnmount=this.componentGracefulUnmount.bind(this)
}
componentGracefulUnmount()组件{
this.setState({mounted:false});
window.removeEventListener('beforeunload',this.componentGracefulUnmount');
}
组件willmount(){
this.setState({mounted:true})
}
componentDidMount(){
//确保已包装实例的componentWillUnmount即使在
//没有时间正确卸载。我们通过
//*在卸载前挂起以进行正常页面浏览
//*在turbolinks上挂接:在呈现turbolinks页面浏览之前
window.addEventListener('beforeunload',this.componentGracefulUnmount);
}
组件将卸载(){
this.componentGracefulUnmount()组件
}
render(){
设{mounted}=this.state;
如果(已安装){
返回
}否则{
return null//强制卸载
}
}
}

}
我真的不明白你为什么要这样做。。如果刷新后不希望状态保持不变,则应在每次状态更改时将状态保存到本地存储中。@Hardy上面的道具已经是数据库集合了。Th
class UpperLevelComponent extends React.Component {

render() {
if(this.props.isReady) {
return(<ChildComponent {...props}/>)
}
}
}

export default createContainer(() => {
const data = Meteor.subscribe("myData");
const isReady = data.ready();

return {
isReady,
data: MyData.find.fetch()
}
})