【问题标题】:Handling logout properly with React Native使用 React Native 正确处理注销
【发布时间】:2018-01-15 18:37:46
【问题描述】:

我有一个 react native 应用程序,它根据是否有经过身份验证的 firebase 用户显示不同的导航器。

这是我的主要 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>
    );
  }
}

现在,当用户登录时重新呈现正确的导航器时,这可以很好地工作。

我遇到的问题是注销。在我的MainNavigator(用户登录时显示的那个)中,我有一个注销按钮,用于注销用户。像这样实现:

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

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

这符合预期,但是,我收到以下我想要解决的警告:

警告:只能更新已安装或已安装的组件。这通常意味着您在未安装的组件上调用了 setState、replaceState 或 forceUpdate。这是无操作的。

实现此注销功能的最佳做法是什么?

编辑:我正在使用react-navigation 库来管理我的应用程序导航。

【问题讨论】:

  • 您使用哪个库进行导航?
  • @GabrielDiez 反应导航

标签: reactjs firebase react-native firebase-authentication react-navigation


【解决方案1】:

我认为根据 App 组件的状态生成 Navigator 可能很危险,并可能导致此问题。在注销时,您应该重定向到负责注册或登录的组件,并且不要让负责此操作的状态重新生成另一个导航的一部分。

你可以做的是在你的 App Component 中,而不是返回 MainNavigator 或 AuthNavigator,你可以返回 Navigator 并添加一个名为 Loading 的 Route,例如,谁将呈现加载屏幕,谁将是负责路由的 initialRoute您的应用取决于用户是否已登录。

本案例的 StackNavigator 示例

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

在您的 LoadingComponent 中,您将渲染您的微调器

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

并且在 LoadingComponent 的 componentDidMount 中:

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

当你打开你的应用程序时会显示加载屏幕,然后根据用户是否登录重定向到好的页面。

并在您的 signOutUser 重定向到登录页面

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

【讨论】:

  • 您能否提供更多关于“在您的应用程序中返回完整导航以及初始加载屏幕”的含义的示例?
  • @BarryMichaelDoyle 我提供了一些例子,希望清楚
  • 谢谢,我现在试试。
  • 我有一个后续问题:stackoverflow.com/questions/45575437/…
  • 应该componentDidMount() 使用async-await 运行firebase.auth().onAuthStateChanged(....) 吗?当我在这段代码中没有 async-await 时,我的 LoadingComponent 永远不会导航到任何地方(将 console.log() 语句添加到 componentDidUpdate 显示 onAuthStateChanged 永远不会触发)。这里有什么问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 2018-06-15
  • 1970-01-01
  • 2020-01-10
  • 2010-09-22
  • 2013-09-27
  • 1970-01-01
相关资源
最近更新 更多