React Navigation V5 的发布和之前版本写法上有些不同,这篇文章就讲Stack,BottomTab,Drawer使用和登录权限认证
v5移除了createSwitchNavigator
登录权限认证会和之前有些变动
在新版React Navigation V5中使用的新的HOC模式,只需要在应用最外层包裹 NavigationContainer
import React from 'React'
import { NavigationContainer } from '@react-navigation/native';
export default function App() {
return (
<NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
);
}
文章涉及代码:github
开始使用React Navigation V5
createStackNavigator
· StackNavigator
现在的写法类似数据结构的堆栈
默认情况下屏幕的跳转方式 ios 从右侧滑入,android 从底部划入,可以在ScreenOptions
中设置屏幕的跳转方式 cardStyleInterpolator文档
screenOptions={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
}}>
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import {HomeScreen, DetailsScreen} from './Screen';
const Stack = createStackNavigator();
function StackScreen() {
return (
<Stack.Navigator
screenOptions={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
}}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<StackScreen />
</NavigationContainer>
);
}
createDrawerNavigator
93rpr-zkv73.gif
点击按钮或从屏幕侧边划入显示抽屉界面
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createDrawerNavigator} from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function DrawerScreen() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Setting" component={SettingScreen} />
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<DrawerScreen/>
</NavigationContainer>
);
}
createBottomTabNavigator
屏幕底部TabBar
import React from 'react';
import {View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
const TabBarIcon = (focused, color) => {
return (
<View
style={{
width: focused ? 24 : 18,
height: focused ? 24 : 18,
backgroundColor: color,
}}
/>
);
};
function TabScreen() {
return (
<Tab.Navigator
tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
screenOptions={{
tabBarIcon: ({focused, color}) => {
return TabBarIcon(focused, color);
},
}}>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{title: '首页'}}
/>
<Tab.Screen
name="Mine"
component={MineScreen}
options={{title: '我的'}}
/>
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<TabScreen />
</NavigationContainer>
);
}
Stack,Drawer,BottomTab结合使用
import React from 'react';
import {View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {
createStackNavigator,
CardStyleInterpolators,
} from '@react-navigation/stack';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {HomeScreen, DetailsScreen, SettingScreen, MineScreen} from './Screen';
const Stack = createStackNavigator();
function StackScreen() {
return (
<Stack.Navigator
screenOptions={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
}}>
<Stack.Screen name="Drawer" component={DrawerScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
);
}
const Drawer = createDrawerNavigator();
function DrawerScreen() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Tab" component={TabScreen} />
<Drawer.Screen name="Setting" component={SettingScreen} />
</Drawer.Navigator>
);
}
const Tab = createBottomTabNavigator();
const TabBarIcon = (focused, color) => {
return (
<View
style={{
width: focused ? 24 : 18,
height: focused ? 24 : 18,
backgroundColor: color,
}}
/>
);
};
function TabScreen() {
return (
<Tab.Navigator
tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
screenOptions={{
tabBarIcon: ({focused, color}) => {
return TabBarIcon(focused, color);
},
}}>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{title: '首页'}}
/>
<Tab.Screen
name="Mine"
component={MineScreen}
options={{title: '我的'}}
/>
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<StackScreen />
</NavigationContainer>
);
}
登录权限认证
v5版本之前可以使用createSwitchNavigator
做登录身份认证,在V5版本移除了这个方法,可以使用V5新特性,根据状态定义和更改导航器的内容
本次使用react Context
进行管理,也可根据项目需要使用redux
和mobx
1.创建context
import React from 'react';
export const AuthContext = React.createContext();
2.屏幕导航
// screen
export function SettingScreen() {
const {signOut} = React.useContext(AuthContext);
return (
<BaseCenterView>
<Text>设置</Text>
<Button
title="退出登录"
onPress={() => {
signOut();
}}
/>
</BaseCenterView>
);
}
export function SignInScreen() {
const {signIn} = React.useContext(AuthContext);
return (
<BaseCenterView>
<Text>登录页面</Text>
<Button
title="登录"
onPress={() => {
signIn();
}}
/>
</BaseCenterView>
);
}
export function SplashScreen() {
return (
<BaseCenterView>
<Text>loading...</Text>
</BaseCenterView>
);
}
// Auth屏幕堆栈
const AuthStack = createStackNavigator();
const AuthStackScreen = () => (
<AuthStack.Navigator headerMode="none">
<AuthStack.Screen name="SignIn" component={SignInScreen} />
</AuthStack.Navigator>
);
// APP堆栈
const Drawer = createDrawerNavigator();
function DrawerScreen() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Tab" component={TabScreen} />
<Drawer.Screen name="Setting" component={SettingScreen} />
</Drawer.Navigator>
);
}
const Tab = createBottomTabNavigator();
const TabBarIcon = (focused, color) => {
return (
<View
style={{
width: focused ? 24 : 18,
height: focused ? 24 : 18,
backgroundColor: color,
}}
/>
);
};
function TabScreen() {
return (
<Tab.Navigator
tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
screenOptions={{
tabBarIcon: ({focused, color}) => {
return TabBarIcon(focused, color);
},
}}>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{title: '首页'}}
/>
<Tab.Screen
name="Mine"
component={MineScreen}
options={{title: '我的'}}
/>
</Tab.Navigator>
);
}
const MainStack = createStackNavigator();
function MainStackScreen() {
return (
<MainStack.Navigator
screenOptions={{
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
}}>
{/* <MainStack.Screen name="Drawer" component={DrawerScreen} /> */}
<MainStack.Screen name="Home" component={HomeScreen} />
<MainStack.Screen name="Details" component={DetailsScreen} />
</MainStack.Navigator>
);
}
// Root堆栈
const RootStack = createStackNavigator();
const RootStackScreen = ({userToken = false}) => (
<RootStack.Navigator headerMode="none">
{userToken ? (
<RootStack.Screen
name="App"
component={MainStackScreen}
options={{
animationEnabled: false,
}}
/>
) : (
<RootStack.Screen
name="Auth"
component={AuthStackScreen}
options={{
animationEnabled: false,
}}
/>
)}
</RootStack.Navigator>
);
// 主路由
export default () => {
const [isLoading, setIsLoading] = React.useState(true);
const [userToken, setUserToken] = React.useState(null);
const authContext = React.useMemo(() => {
return {
signIn: () => {
setIsLoading(false);
setUserToken('asdf');
},
signUp: () => {
setIsLoading(false);
setUserToken('asdf');
},
signOut: () => {
setIsLoading(false);
setUserToken(null);
},
};
}, []);
React.useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000);
}, []);
if (isLoading) {
return <SplashScreen />;
}
return (
<AuthContext.Provider value={authContext}>
<NavigationContainer>
<RootStackScreen userToken={userToken} />
</NavigationContainer>
</AuthContext.Provider>
);
};
结束