导航问题-无法在未安装的组件上执行React状态更新

时间:2019-08-05 21:50:14

标签: reactjs react-native react-navigation react-native-ios

我得到了

  

ExceptionsManager.js:94警告:无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要解决此问题,请在componentWillUnmount方法中取消所有订阅和异步任务。   在TabView中(位于createMaterialTopTabNavigator.js:248)

仅当我尝试使用 createMaterialTopNavigator 渲染屏幕时,才会发生这种情况。我推测我的问题可能与我如何构建导航页面有关。在重新配置导航时,我愿意接受其他选择!

我已经完成了研究,并且尝试了  this.setState({signedIn:false}), this.AuthorizeFireBaseUser()中的componentWillUnmount 但是一切都没有成功。

Router.js (我所有的导航/屏幕都在其中)

const SignedOut =  createStackNavigator({
    SignIn:{screen:SignIn},
    CreateAccount:{screen:CreateAccount},
    Profile:{screen:Profile}
  });

  const SignedIn = createMaterialBottomTabNavigator({
   Home:{screen:Main},    //where my top tab navigator lives
   Profile:{screen:Profile}
  });


class Router extends React.Component{
    constructor(){
        super();
        this.state={
            signedIn:false,
        }
    }

    RootNavigator = (signedIn)=>{
        return createSwitchNavigator({
            SignedIn:{screen:SignedIn},
            SignedOut:{screen:SignedOut}
        },
        {
            initialRouteName: this.state.signedIn ? "SignedIn" : "SignedOut"  //if signedIn is true head to signedIn else head to SignOut screens
        });


    }

    AuthorizeFirebaseUser(){
        firebase.auth().onAuthStateChanged(user=>{
            if(user){
              this.setState({signedIn:true});
            }
        });

    }

    componentDidMount(){ //Checking if user is signed in will run in background upon loading
       this.AuthorizeFirebaseUser(); //if user is signed in set state to true 
    }

    componentWillUnmount(){
      // unsure what to unmount 
    }

    render(){
        const {signedIn} = this.state;
        const Layout = createAppContainer(this.RootNavigator(signedIn)); // when this page renders it'll call the rootnav function - check state , and render the appropriate screens 
        return <Layout />

    }
}//end bracket
export default Router;

Router类返回Layout,该Layout调用函数RootNavigator来确定要显示的屏幕(取决于用户是否登录)。

Main.js -是我的 createMaterialTopNavigator 的住所,它将呈现两个主页面。 我在主屏幕中的const = SignedIn->中调用 Main.js

const Tabs = createMaterialTopTabNavigator({
    Newsfeed:{screen: Newsfeed},
    Services:{screen:Services}
},
{
    initialRouteName:'Services',
    swipeEnabled:true,
    navigationOptions:({navigation})=>({
         header:null

    }),
    tabBarOptions:{
        activeTintColor:'#65FAE9',
        inactiveTintColor:'white',
        allowFontScaling:true,
        indicatorStyle:{borderBottomColor:'#65FAE9', borderBottomWidth:4,},
        style:{backgroundColor:'#515276'},
        labelStyle:{marginTop:'40%',fontSize:15},  
    },     
 },

);

export default Tabs; 

App.js

export default class App extends React.Component {
  render() {
    return <Router />
  }
}

我不确定如何解决此警告,内存泄漏永远不会消失。我愿意接受所有有关修复导航结构的建议,因为我认为这可能是个问题。我也是React-native / React初学者。在此先感谢!

1 个答案:

答案 0 :(得分:0)

setState()是异步的。因此,我认为您的组件将在setState()完成状态设置之前被卸载。

您可以使用变量来跟踪并检查组件是否仍在安装中。

isMounted = false // Initially

componentDidMount() { this.isMounted = true; }

componentWillUnmount() { this.isMounted = false; }

现在仅在确认seState()仍然为真之后使用isMounted

希望这会有所帮助!