我已经实现了一个React Native应用程序。目前,该应用程序在加载屏幕上打开,加载屏幕在安装后检查firebase.auth().onAuthStateChanged(...)
功能。
应用程序基本上决定是否进入登录屏幕或主屏幕,具体取决于用户是否已经过身份验证。
它是这样实现的:
主导航:
const MainNavigator = TabNavigator({
auth: {
screen: TabNavigator({
login: { screen: LoginScreen },
signup: { screen: SignupScreen }
}, {
initialRouteName: 'login',
tabBarPosition: 'top',
lazy: true,
animationEnabled: true,
swipeEnabled: true,
tabBarOptions: {
labelStyle: { fontSize: 12 },
showIcon: true,
iconStyle: { width: 30, height: 30 }
}
})
},
main: {
screen: StackNavigator({
notes: { screen: NotesScreen }
}, {
initialRouteName: 'notes'
})
},
loading: { screen: LoadingScreen }
}, {
initialRouteName: 'loading',
lazy: true,
swipeEnabled: false,
animationEnabled: false,
navigationOptions: {
tabBarVisible: false
}
});
载入画面:
class LoadingScreen extends Component {
componentDidMount() {
const { navigate } = this.props.navigation;
firebase.auth().onAuthStateChanged(user => {
if (user) {
navigate('main');
} else {
navigate('auth');
}
});
}
render() {
return (
<View style={styles.spinnerStyle}>
<Spinner size="large" />
</View>
);
}
}
const styles = {
spinnerStyle: {
flexDirection: 'row',
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
};
除了一个问题之外,这很有效。
当我按下Android的硬件返回按钮时,它会转到应用程序加载屏幕,这显然是不受欢迎的。我该如何预防?
修改
我已经尝试了以下操作,它也没有工作:
const resetAction = (routeName) => NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName })],
key: null
});
class LoadingScreen extends Component {
componentDidMount() {
const { dispatch } = this.props.navigation;
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.props.setUser(user);
dispatch(resetAction('main'));
} else {
dispatch(resetAction('auth'));
}
});
}
render() {
return (
<View style={styles.spinnerStyle}>
<Spinner size="large" />
</View>
);
}
}
答案 0 :(得分:1)
尝试使用自定义后退按钮支持的自定义导航组件。别忘了将reducer添加到yoru combine reducers函数中。
创建导航组件:
import React, { Component } from 'react';
import { BackHandler } from 'react-native';
import { connect } from 'react-redux';
import { addNavigationHelpers } from 'react-navigation';
import MainNavigator from './MainNavigator';
class AppWithNavigationState extends Component {
componentDidMount () {
BackHandler.addEventListener('hardwareBackPress', () => {
this.props.dispatch({
type: 'Navigation/BACK'
});
return true;
});
}
componentWillUnmount () {
BackHandler.removeEventListener('hardwareBackPress');
}
render () {
return (
<MainNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav
})}/>
);
}
}
export default connect((state) => ({ nav: state.nav }))(AppWithNavigationState);
创建导航缩减器:
import { NavigationActions } from 'react-navigation';
import MainNavigator from './MainNavigator';
import { NAVIGATION_ON_SIGN_IN } from '../redux/actions/ActionTypes';
import { BackHandler } from 'react-native';
const initialState = MainNavigator.router.getStateForAction(MainNavigator.router.getActionForPathAndParams('loading'));
function appShouldClose (nextState) {
const { index, routes } = nextState;
return index === 0 || routes[1].routeName === 'auth';
}
export default (state = initialState, action) => {
const { router } = MainNavigator;
let nextState;
switch (action.type) {
case NavigationActions.BACK:
nextState = router.getStateForAction(action, state);
appShouldClose(nextState) && BackHandler.exitApp();
break;
default:
nextState = router.getStateForAction(action, state);
}
return nextState || state;
};
答案 1 :(得分:1)
使用切换导航器,直到用户成功登录(加载和登录页面),然后再使用堆栈导航器(用户主页和随后的其他页面)。
switchNavigator(loading, login, stackNavigator)
stackNavigator(user homepage,....)
答案 2 :(得分:0)
这是我的解决办法:)
我有StageArea页面。它是从登录到时间线之间的桥梁。用户没有登录然后转到LoginPage。用户登录然后转到时间轴。用户按下后退按钮然后再次进入TimeLine页面而不进入登录页面。(Sory for my english)
import React, { Component } from 'react';
import { View } from 'react-native';
import LoginForm from './LoginForm';
import Timeline from './Timeline';
import firebase from 'firebase';
import InitialPage from './InitialPage'
class StageArea extends Component {
state = {isLoggin:''};
componentWillMount(){
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.setState({ isLoggin:true})
}else {
this.setState({ isLoggin:false})
}
})
}
render() {
if(this.state.isLoggin)
{
return(<Timeline/>);
}
else if (this.state.isLoggin===false) {
return(<LoginForm/>);
}
}
}
export default StageArea;
答案 3 :(得分:-1)
写下面的代码,
static navigationOptions = {
header:null
};
就在
之前render() {
return (
NotesScreen 上的,没有任何后退按钮。