项目需求
普通登录项目的跳转流程
- 闪屏(splash)->登录页->首页
- 闪屏(splash)->首页 (以登录)
通过context 在个页面中传递数据,新建context的工具类
export const AuthContext = React.createContext();
页面需要用AuthContext.Provider 包装
if (state.isLoading) { //splash
return <AuthContext.Provider value={authContext}>
<SplashScreen></SplashScreen>
</AuthContext.Provider>
}
return (
<NavigationContainer>
<AuthContext.Provider value={authContext}>
{
state.userToken == null ? ( //未登录
<Stack.Navigator screenOptions={{ headerShown: true }}>
<Stack.Screen name="Login" component={LoginScreen} options={{ title: "登录" ,animationTypeForReplace: state.isSignout ? 'pop' : 'push'}} />
</Stack.Navigator>) : ( //已登录
<Stack.Navigator screenOptions={{ headerShown: true }}>
<Stack.Screen name="Tab" component={HomeTab} options={{ title: "首页" }} />
<Stack.Screen name="List" component={ListScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>)
}
</AuthContext.Provider>
</NavigationContainer>
)
在个页面通过context获取值,function组件使用useContext(),详见HookApi
static contextType = AuthContext;
this.context
完整代码
首页
import 'react-native-gesture-handler';
import React, { Component, useState,useEffect } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { Image, Button, View, Text, StyleSheet } from 'react-native'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
//引入页面模块
import HomeScreen from './HomeScreen';
import ListScreen from './ListScreen'
import Setting from './Setting'
import ProfileScreen from './ProfileScreen'
import SplashScreen from './SplashScreen'
import LoginScreen from './LoginScreen'
import {AuthContext} from './Util'
function Tab() {
const RootTab = createBottomTabNavigator();
const Stack = createStackNavigator()
function switchState(state,action){
switch (action.type) {
case 'RESTORE_TOKEN':
return {
...state,
userToken: action.token,
isLoading: false,
};
case 'SIGN_IN':
return {
...state,
isSignout: false,
userToken: action.token,
};
case 'SIGN_OUT':
return {
...state,
isSignout: true,
userToken: null,
};
}
}
const [state,dispatch] = React.useReducer(switchState,{
isLoading: true,
isSignout: false,
userToken: null,
});
const authContext = React.useMemo(
() => ({
splashOver: ()=>dispatch({type:"RESTORE_TOKEN"}),
signIn: async data => {
// 添加登录逻辑
await xxxx
console.log("login"+data)
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
},
signOut: () => dispatch({ type: 'SIGN_OUT' }),
signUp: async data => {
dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
},
}),
[]
);
if (state.isLoading) { //splash
return <AuthContext.Provider value={authContext}>
<SplashScreen></SplashScreen>
</AuthContext.Provider>
}
return (
<NavigationContainer>
<AuthContext.Provider value={authContext}>
{
state.userToken == null ? ( //未登录
<Stack.Navigator screenOptions={{ headerShown: true }}>
<Stack.Screen name="Login" component={LoginScreen} options={{ title: "登录" ,animationTypeForReplace: state.isSignout ? 'pop' : 'push'}} />
</Stack.Navigator>) : ( //已登录
<Stack.Navigator screenOptions={{ headerShown: true }}>
<Stack.Screen name="Tab" component={HomeTab} options={{ title: "首页" }} />
<Stack.Screen name="List" component={ListScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>)
}
</AuthContext.Provider>
</NavigationContainer>
)
}
function HomeTab(params) {
//...
return (
<RootTab.Navigator screenOptions={screenOptionss} tabBarOptions={tabBarOptions}>
<RootTab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3, title: "首页" }}
/>
<RootTab.Screen name="Settings" options={{ tabBarBadge: 3, title: "设置" }} component={Setting} />
</RootTab.Navigator>
)
}
export default Tab;
splash页面
import React, { Component} from 'react';
import {View,Text,SafeAreaView,Button} from 'react-native'
import {AuthContext} from './Util'
class SplashScreen extends Component {
static contextType = AuthContext;
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <SafeAreaView>
<Text>spalash view</Text>
<Button title="over" onPress={this.context.splashOver}></Button>
</SafeAreaView> );
}
}
export default SplashScreen;
登录页
export default class LoginScreen extends Component {
constructor(props) {
super(props);
}
static contextType = AuthContext;
render() {
return (
<View>
<Button title="登录" onPress={this.onAlert.bind(this)}></Button>
</View>
)
}
onAlert = () => {
Alert.alert("提示", "是否登录", [
{
text: "是",
onPress: () => {
this.context.signIn({name:"jack",password:"123"});
console.log("登录了!!!")
}
},
{
text: "否",
onPress: () => {
console.log("取消登录" )
}
}
])
}
}
退出登录
class ProfileScreen extends Component {
static contextType = AuthContext;
render() {
return ( <View>
<Text>Profile </Text>
<Button title="退出登录" onPress={this.context.signOut}></Button>
</View> );
}
}