web-dev-qa-db-ja.com

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ライブラリを使用しています。

6

アプリコンポーネントの状態に応じてナビゲーターを生成することは危険であり、この問題につながる可能性があると思います。ログアウト時に、登録またはログインを担当するコンポーネントにリダイレクトする必要があります。別のナビゲーションの一部を再生成して、これを担当する状態にさせないでください。

あなたができることはあなたのアプリコンポーネントで、MainNavigatorまたはAuthNavigatorを返す代わりに、両方のナビゲーターを返し、たとえば、ロード画面をレンダリングし、だれがアプリのルーティングを担当するinitialRouteになるLoadingというルートを追加できます。ユーザーが記録されているかどうか。

このケースでの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 = async () => {
    try {
        await firebase.auth().signOut();
        navigate('Auth');
    } catch (e) {
        console.log(e);
    }
}
11
Gabriel Diez