简体   繁体   English

使用React Native正确处理注销

[英]Handling logout properly with React Native

I have a react native application that show's different navigators based on whether or not there is an authenticated firebase user. 我有一个react本机应用程序,根据是否有经过身份验证的firebase用户显示不同的导航器。

Here's my main App class: 这是我的主要App类:

export default class App extends Component {
  state = { loggedIn: null }

  componentWillMount() {
    firebase.initializeApp({...});

    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.setState({ loggedIn: true });
      } else {
        this.setState({ loggedIn: false });
      }
    });
  }

  renderContent() {
    switch (this.state.loggedIn) {
      case true:
        return (
          <MenuContext>
            <MainNavigator />
          </MenuContext>
        );
      case false:
        return (
          <AuthNavigator />
        );
      default:
        return (
          <View style={styles.spinnerStyle}>
            <Spinner size="large" />
          </View>
        );
    }
  }

  render() {
    return (
      <Provider store={store}>
        {this.renderContent()}
      </Provider>
    );
  }
}

Now this works perfectly fine with re-rendering the correct Navigator when a user logs in. 现在,当用户登录时,重新渲染正确的Navigator可以很好地工作。

The problem I have is with logging out. 我遇到的问题是退出。 In my MainNavigator (the one that shows when a user is logged in), I have a logout button which logs the user out. 在我的MainNavigator (用户登录时显示的那个)中,我有一个注销按钮,用于将用户注销。 Implemented like this: 像这样实现:

signOutUser = async () => {
    try {
        await firebase.auth().signOut();
    } catch (e) {
        console.log(e);
    }
}

render() {
    return (
        ...
        <Button title="logout" onPress={() => this.signOutUser()} />
    )
}

This does what is expected, however, I get the following warning which I want to resolve: 这可以达到预期效果,但是,我得到以下警告我要解决的问题:

Warning: Can only update a mounted or mounting component. 警告:只能更新已安装或安装的组件。 This usually means you called setState, replaceState or forceUpdate on an unmounted component. 这通常意味着您在已卸载的组件上调用了setState,replaceState或forceUpdate。 This is a no-op. 这是一个无操作。

What is the best practice way of implementing this logout functionality? 实现此注销功能的最佳实践方法是什么?

Edit: I'm using the react-navigation library for managing my application navigation. 编辑:我正在使用react-navigation库来管理我的应用程序导航。

I think generating your Navigator depending on a state of App component can be dangerous and can lead to this issue. 我认为根据应用程序组件的状态生成导航器可能很危险,并可能导致此问题。 On logout you should redirect to the component in charge of registration or login and don't let the state in charge of this with regenerating a part of an another navigation. 注销时,您应该重定向到负责注册或登录的组件,并且不要让负责此操作的状态重新生成另一个导航的一部分。

What you can do is in your App Component, instead of returning MainNavigator or AuthNavigator, you can return both Navigator and add a Route called Loading for example, who will render a loading screen and who will be the initialRoute in charge of routing your app depending on the user is logged or not. 您可以做的是在App Component中,而不是返回MainNavigator或AuthNavigator,您可以返回两个Navigator并添加一个名为Loading的路由,例如,谁将呈现一个加载屏幕,谁将是负责路由您的应用程序的initialRoute取决于是否记录了用户。

Example of StackNavigator with this case 这种情况下的StackNavigator示例

const Navigator = StackNavigator({
  Main: {
    screen: MainComponent,
  },
  Auth: {
    screen: AuthComponent,
  },
  Loading: {
    screen: LoadingComponent
  },
},{
    initialRouteName : 'Loading'
});

in your LoadingComponent you will render your spinner 在您的LoadingComponent中,您将渲染您的微调器

render() {
  return(
    <View style={styles.spinnerStyle}>
      <Spinner size="large" />
    </View>
  );
}

And in componentDidMount of LoadingComponent : 在LoadingComponent的componentDidMount中:

firebase.auth().onAuthStateChanged(user => {
  if (user) {
      navigate('Home');
  } else {
      navigate('Login');
  }
});

With that the loading screen will be display when you open your app and then redirect to the good page depending of user is logged or not. 这样,当您打开应用程序时,将显示加载屏幕,然后根据用户是否记录重定向到好页面。

And in your signOutUser redirect to Login page 并在您的signOutUser重定向到登录页面

signOutUser = async () => {
    try {
        await firebase.auth().signOut();
        navigate('Auth');
    } catch (e) {
        console.log(e);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM