我在使用高阶组件检查用户是否已通过身份验证(checkAuth)时遇到问题。我的问题是,该路由似乎没有受到保护,因为它没有显示在屏幕上,但它确实加载了底部的标签导航,标题,并且没有路由回到“登录”屏幕。
HERE'S WHAT THE ISSUE LOOKS LIKE
checkAuthTest只是我编写的用于导航到“对话”屏幕的功能:
// Check Auth Test (Testing)
checkAuthTest = () => {
try {
console.log('Navigating to App Stack')
console.log(`Current User: ${firebase.auth().currentUser}`);
// this.props.navigation.navigate('AppStack');
// this.props.navigation.navigate('AuthLoading');
this.props.navigation.navigate('Conversations');
}
catch (error) {
console.log(error);
}
};
高阶组件:
如果用户通过了身份验证,那么高级组件会将用户路由到该组件。如果用户未通过身份验证,则高阶组件会将用户引导回登录屏幕。
// Imports: Dependencies
import React from 'react';
import firebase from 'firebase';
// Imports: Screens
import Login from '../../screens/auth-stack/Login';
// Higher Order Component: Check Auth
const CheckAuth = (OriginalComponent) => props => {
class CheckAuth extends React.Component {
render() {
// Check Authentication (Working)
if (firebase.auth().currentUser !== null) {
return <OriginalComponent {...this.props} />
}
// Redirect To Login (Not Working)
else {
return <Login />
}
}
}
// Return Check Auth Component
return CheckAuth;
}
// Exports
export default CheckAuth;
反应导航: 我正在使用React Navigation,这是我的设置:
// React Navigation: Auth Stack Navigator
export const AuthStack = createStackNavigator({
Login: Login,
AuthLoading: AuthLoading,
});
// React Navigation: Messaging Stack Navigator
export const MessagingStack = createStackNavigator({
Conversations: Conversations,
Message: Message,
NewMessage: NewMessage,
});
// React Navigation: Profile Stack Navigator
export const ProfileStack = createStackNavigator({
Profile: Profile,
},
{
mode: 'modal',
});
// React Navigation: App Stack Navigator
export const AppStack = createBottomTabNavigator({
Message: {
screen: MessagingStack,
navigationOptions: {
tabBarLabel: 'Message',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-chatboxes" color={tintColor} size={26} />
),
}
},
Profile: {
screen: ProfileStack,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-contact" color={tintColor} size={28} />
),
}
}
});
// React Navigation: Switch Container
export const AppContainer = createAppContainer(createSwitchNavigator(
{
AuthStack: AuthStack,
AppStack: AppStack,
},
// Options
{
initialRouteName: 'AuthStack',
// initialRouteName: 'AppStack',
}
));
对话屏幕导出:
export default connect(mapStateToProps, mapDispatchToProps)(checkAuth(Conversations));
登录组件
// Imports: Dependencies
import React, { Component } from 'react';
import { Button, SafeAreaView, StyleSheet, Text } from 'react-native';
import { connect } from 'react-redux';
// Imports: Redux Actions
import {
loginWithAppleRequest,
} from '../../redux/actions/authActions';
// TEST: Delete Later
import firebase from 'firebase';
import { appleAuth } from '../../firebase/firebase';
// Imports: Components
import FBLoginButton from '../../components/FacebookLoginButton';
import GoogleLoginButton from '../../components/GoogleLoginButton';
import SignOutButton from '../../components/SignOutButton';
// Screen: Login
class Login extends Component {
constructor(props) {
super(props);
}
// React Navigation: Options
static navigationOptions = {
headerStyle: {
elevation: 0,
shadowOpacity: 0,
borderBottomWidth: 0,
}
};
// Login With Apple
loginWithApple = () => {
try {
firebase
.auth()
.signInWithPopup(appleAuth)
.then((result) => {
// The signed-in user info.
let user = result.user;
// You can also get the Apple OAuth Access and ID Tokens.
let accessToken = result.credential.accessToken;
let idToken = result.credential.idToken;
console.log('User');
console.log(user);
console.log('Access Token');
console.log(accessToken);
console.log('ID Token');
console.log(idToken);
})
.catch((error) => {
// Handle Errors here.
let errorCode = error.code;
let errorMessage = error.message;
// The email of the user's account used.
let email = error.email;
// The firebase.auth.AuthCredential type that was used.
let credential = error.credential;
console.log('Error Code');
console.log(errorCode);
console.log('Error Message');
console.log(errorMessage);
console.log('Email');
console.log(email);
console.log('Credential');
console.log(credential);
});
}
catch (error) {
console.log(error);
}
};
// Check Auth Test (Testing)
checkAuthTest = () => {
try {
console.log('Navigating to App Stack')
console.log(`Current User: ${firebase.auth().currentUser}`);
// this.props.navigation.navigate('AppStack');
// this.props.navigation.navigate('AuthLoading');
this.props.navigation.navigate('Conversations');
}
catch (error) {
console.log(error);
}
};
render() {
return (
<SafeAreaView style={styles.container}>
<GoogleLoginButton />
<FBLoginButton />
<Button onPress={this.checkAuthTest} title="Check Auth Test" />
<SignOutButton />
</SafeAreaView>
)
}
}
// Styles
const styles = StyleSheet.create({
container: {
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
});
// Map State To Props (Redux Store --> Component)
const mapStateToProps = (state) => {
// Redux Store --> Component
return {
// uid: state.authReducer.uid,
};
};
// Map Dispatch To Props (Dispatch Actions To Redux Store To Grab Data)
const mapDispatchToProps = (dispatch) => {
// Action
return {
// Redux: Dispatch Login With Apple Action
reduxLoginWithAppleRequest: () => dispatch(loginWithAppleRequest()),
};
};
// Exports
export default connect(mapStateToProps, mapDispatchToProps)(Login);
答案 0 :(得分:1)
该错误告诉您出了什么问题。您要返回的是函数而不是元素:
const CheckAuth = (OriginalComponent) => props => {
class CheckAuth extends React.Component {
// ...
}
// Return Check Auth Component
return CheckAuth;
}
现在使用时:
CheckAuth(Conversations)
结果:
const Component = props => {
class CheckAuth extends React.Component {
// ...
}
// This is a component but you're returning a function instead an element
return CheckAuth;
}
您可能想要:
const CheckAuth = (OriginalComponent) => {
class CheckAuthComponent extends React.Component {
// ...
}
// Return Check Auth Component
return CheckAuthComponent;
}
这里,我删除了多余的props =>
,因为您需要在此处返回组件(CheckAuth
),而不是返回组件的函数(props => CheckAuth
)。