javascript - this.props.navigation.navigate 在 onAuthChanged() 中不起作用
问题描述
我是 React Native 编程的新手,并决定通过集成 Firebase 功能来深入研究。我的所有布局都正常工作,但是当我尝试为 Firebase 身份验证编写代码时遇到问题。
问题出在我检查用户是否经过身份验证的一开始(启动画面)(onAuthChanged)。如果已加载用户对象,那么我想在用户对象为空时重定向到登录页面,并在存在有效用户对象时重定向到加载(主)页面。
当满足这些条件但没有任何反应时,想要使用简单的 react-navigation this.props.navigation.navigate 调用。没有重定向,也没有错误。
很确定这一定是我的基本错误,但我找不到。所有相关代码都在 ComponentDidMount()
闪屏.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,它是从 App,js 调用的 StackNavigator 屏幕
应用程序.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 />;
}
}
有人可以告诉我哪里出了问题或提出更好的处理方法吗?谢谢
解决方案
componentDidMount
仅在初始渲染后立即触发一次。
this.setState 不是瞬时的。在您的情况下, this.setState 在 this 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 仍然是假的。
永远不要期望 setState 是同步的或瞬时的,恰恰相反。
解决方案是删除 userLoading 并在 this.state.user 确定后立即导航到下一个屏幕。
推荐阅读
- javascript - 如何在单独的行上打印数组的每个元素?
- laravel - Laravel:“试图获取非对象的属性'评论'”
- python - 使用 OpenCV 增强灯的角检测
- flutter - 只有一个字符的小容器没有正确居中 - Flutter
- html - 中心响应式导航栏
- angular - 不同 NGRX 效果导致相同动作但在某些情况下连续触发时的最佳实践
- java - Spring:映射并将值作为对象形式传递给控制器以查看
- javascript - 导入配置变量
- python - 你能找出我的 BFS 代码中的错误吗
- java - 如何在DataChange Firebase上返回数据