react-navigation 企业级路由框架搭建

环境配置

  • "react-native": "0.74.3",
  • "@react-navigation/native": "^6.1.17",
  • "@react-navigation/native-stack": "^6.10.0",
  • "react-native-safe-area-context": "^4.10.8",
  • "react-native-screens": "^3.32.0",

贴上我当前的版本,没想到现在的RN弄一套路由框架,需要这么多库

react-navigation API介绍

reactnavigation.org/

设计思路

我把APP大致分为3层。从下到上分别是【业务、登录、Debug】,Debug层级最高,方便我们随时随地查看。当然也可以按照实际业务来,划分的更多

1. 定义各个层

debug-stack.tsx

js 复制代码
/**
 * Debug模块
 */
const DebugStack = createNativeStackNavigator()
export const DebugModule = () => {
	return (
		<DebugStack.Navigator
			initialRouteName={"Debug"}
			screenOptions={{
				headerShown: false,
			}}
		>
			<DebugStack.Screen name={"Debug"} component={DebugScreen} />
			<DebugStack.Screen
				name={"DeviceInfoDemo"}
				component={DeviceInfoDemo}
				options={{
					animation: "slide_from_right",
				}}
			/>
			<DebugStack.Screen
				name={"DatePickerDemo"}
				component={DatePickerDemo}
				options={{
					animation: "slide_from_right",
				}}
			/>
		</DebugStack.Navigator>
	)
}

login-stack.tsx

js 复制代码
/**
 * 登录模块
 */
const LoginStack = createNativeStackNavigator()
export const LoginModule = () => {
	return (
		<LoginStack.Navigator
			initialRouteName={"Debug"}
			screenOptions={{
				headerShown: false,
			}}
		>
			<LoginStack.Screen
				name={"LoginScreen"}
				component={LoginScreen}
				options={
					{
						// headerShown: true,
						// animation: 'fade_from_bottom',
					}
				}
			/>
			<LoginStack.Screen
				name={"LoginAccount"}
				component={LoginAccount}
				options={{
					// headerShown: true,
					animation: "fade_from_bottom",
				}}
			/>
		</LoginStack.Navigator>
	)
}

home-stack.tsx

js 复制代码
/**
 * 主模块
 * 因为我项目里没有底部Tab模块,就直接用堆栈路由
 * 如果有底部Tab的需要改成下面Tab,栈不一样
 */
const HomeStack = createNativeStackNavigator()
export const HomeModule = () => {
	return (
		<>
			<HomeStack.Navigator
				initialRouteName={"SplashScreen"}
				screenOptions={{
					headerShown: false,
				}}
			>
				<HomeStack.Screen
					name={"HomeScreen"}
					component={HomeScreen}
					options={{
						gestureEnabled: false, // 禁止ios左滑手势
					}}
				/>
				<HomeStack.Screen name={"DemoScreen"} component={DemoScreen} />
				<HomeStack.Screen name={"DetailScreen"} component={DetailScreen} />
			</HomeStack.Navigator>
			<DebugButton />
		</>
	)
}

/**
 * 底部tab
 */
// const TabStack = createBottomTabNavigator()
// function Tab() {
//     return (
//         <TabStack.Navigator
//             screenOptions={({ route }) => ({
//                 tabBarIcon: ({ focused }) => {
//                     return <TabIconComponent routeName={route.name} focused={focused} />
//                 }
//             })}
//         >
//             <TabStack.Screen name='Demo' component={DemoScreen} />
//             <TabStack.Screen name='Home' component={HomeScreen} />
//             <TabStack.Screen name='Profile' component={ProfileScreen} />
//         </TabStack.Navigator>
//     )
// }

2. 把各个层合并到一起,给入口文件调用

这里为什么要用state来控制路由呢?

比如登录流程有10个页面,在最后一个页面操作完后想关闭登录流程,虽然可以用路由的跳转或者重定向做到,但是体感不佳。最佳的方式是直接把整个登录路由销毁掉,实测下来体感最佳。

root.tsx

默认入口是SplashScreen,里面会通过登录密钥判断应该去首页还是登录页

ts 复制代码
/**
 * 底层路由库
 */
const RootStack = createNativeStackNavigator()
export const Root = () => {
	const [showLogin, setShowLogin] = useState(true)
	const [showDebug, setShowDebug] = useState(true)

	useEffect(() => {
		if (!showDebug) {
			setTimeout(() => {
				setShowDebug(true)
			}, 100)
		}
	}, [showDebug])

	useEffect(() => {
		if (!showLogin) {
			setTimeout(() => {
				setShowLogin(true)
			}, 100)
		}
	}, [setShowLogin])

	return (
		<GlobalProvider>
			<NavigationContainer>
				<RootRouterContext.Provider value={{ setShowLogin, setShowDebug }}>
					<RootStack.Navigator initialRouteName="SplashScreen">
						<RootStack.Screen
							name="SplashScreen"
							component={SplashScreen}
							options={{ headerShown: false }}
						/>
						<RootStack.Screen
							name="HomeStack"
							component={HomeModule}
							options={{ headerShown: false }}
						/>
						{showLogin && (
							<RootStack.Screen
								name="LoginStack"
								component={LoginModule}
								options={{
									headerShown: false,
									animation: "fade_from_bottom",
								}}
							/>
						)}
						{showDebug && (
							<RootStack.Screen
								name="DebugStack"
								component={DebugModule}
								options={{
									headerShown: false,
									animation: "fade_from_bottom",
								}}
							/>
						)}
					</RootStack.Navigator>
				</RootRouterContext.Provider>
			</NavigationContainer>
		</GlobalProvider>
	)
}

3. 入口文件

js 复制代码
const App = () => {
	return <Root />
}

export default App

OK,完事~,是不是非常简单

相关推荐
gxhlh1 天前
React Native防止重复点击
javascript·react native·react.js
miao_zz1 天前
基于react native的锚点
android·react native·react.js
卿卿qing3 天前
【React Native】路由和导航
javascript·react native·react.js
日渐消瘦 - 来自一个高龄程序员的心声3 天前
react native(expo)多语言适配
javascript·react native·react.js·expo
卿卿qing3 天前
【App】React Native
javascript·react native·react.js
日渐消瘦 - 来自一个高龄程序员的心声3 天前
react native(expo)选择图片/视频并上传阿里云oss
react native·react.js·阿里云
恋猫de小郭4 天前
鸿蒙版 React Native 正式开源,ohos_react_native 了解一下
react native·react.js·harmonyos
恋猫de小郭5 天前
React Native 0.76,New Architecture 将成为默认模式,全新的 RN 来了
javascript·react native·react.js
Atypiape212 天前
(零) React Native 项目开发拾遗
android·flutter·react native·ios·typescript·rn
小童不学前端13 天前
如何在移动端app里嵌套web页面之react-native-webview
react native·expo