this.props.navigation.navigate не работает в onAuthChanged () - PullRequest
0 голосов
/ 22 сентября 2018

Я новичок в программировании на React Native и решил углубиться в глубину, также интегрировав функции Firebase.У меня все мои макеты работают, но при попытке написать код для аутентификации Firebase у меня возникла проблема.

Проблема в самом начале (заставка), где я проверяю, аутентифицирован ли пользователь или нет (onAuthChanged ).Если пользовательский объект был загружен, то я хочу перенаправить на страницу входа, когда пользовательский объект имеет значение null, и на загрузочную (основную) страницу, когда существует допустимый пользовательский объект.

Хотел использовать простую реактивную навигацию по вызову this.props.navigation.navigate, когда эти критерии выполнены, но ничего не происходит.Нет перенаправления, а также нет ошибок.

Я уверен, что это, должно быть, основная ошибка с моей стороны, но я не могу ее найти.Весь соответствующий код находится в ComponentDidMount ()

SplashScreen.js

import React, { Component } from "react";
import {
  View,
  Text,
  StyleSheet,
  SafeAreaView,
  Image,
  TouchableOpacity
} from "react-native";

import { Transition } from "react-navigation-fluid-transitions";
import firebase from "react-native-firebase";

class SplashScreen extends Component {
  constructor(props) {
    super(props);
    this.unsubscriber = null;
    this.state = {
      userLoading: true,
      user: null
    };
  }

  componentDidMount() {
    firebase.auth().onAuthStateChanged(user => {
      console.log("User object = " + JSON.stringify(user));
      console.log("1 - this.props");
      console.log(this.props);
      this.setState({ userLoading: false, user });
      if (!this.state.userLoading && this.state.user) {
        console.log("Loading screen");
        this.props.navigation.navigate("Loading");
      }
      if (!this.state.userLoading && !this.state.user) {
        console.log("Login screen");
        this.props.navigation.navigate("Login");
      }
    });
  }

  componentWillUnmount() {
    if (this.unsubscriber) {
      //this.unsubscriber();
      firebase.unsubscriber();
    }
  }

  render() {
    return (
      <SafeAreaView
        style={{
          flex: 1,
          backgroundColor: "#587AA0",
          alignItems: "center"
        }}
      >
... more layout of the splash screen
}
}
export default SplashScreen;

Все файлы console.logs выводят правильные значения (пользовательский объект и this.props.navigation.navigate присутствует)

Просто ничего не происходит :( Без перенаправления и без ошибок

Этот код предназначен для SplashScreen.js, который является экраном StackNavigator, вызываемым из App, js

App.js

    const LoginStack = FluidNavigator(
  {
    Splash: {
      screen: SplashScreen
    },
    Login: {
      screen: LoginScreen
    },
    Setup: {
      screen: SetupScreen
    },
    Tour: {
      screen: TourScreen
    },
    Loading: {
      screen: LoadingScreen
    },
    Main: {
      screen: MainTab
    }
  },
  {
    initialRouteName: "Splash",
    headerMode: "none"
  }
);

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

Может кто-нибудь сказать мне, где я ошибся, или предложить лучший способ справиться с этим? Спасибо

1 Ответ

0 голосов
/ 22 сентября 2018

componentDidMount запускается только один раз сразу после первоначального рендеринга.

this.setState не является мгновенным.В вашем случае this.setState полностью выполняется ПОСЛЕ этого блока if.

if (!this.state.userLoading && this.state.user) {
    console.log("Loading screen");
    this.props.navigation.navigate("Loading");
}
if (!this.state.userLoading && !this.state.user) {
    console.log("Login screen");
    this.props.navigation.navigate("Login");
}

Следовательно, этот блок if не будет выполнен, поскольку this.state.userLoading все еще имеет значение false.

Никогда не ожидайте, что setState будет синхронным или мгновенным, это как раз наоборот.

Решение состоит в том, чтобы просто удалить userLoading и сразу перейти к следующему экрану после определения this.state.user.

...