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,完事~,是不是非常简单

相关推荐
wordbaby9 小时前
Expo 进阶指南:赋予 TanStack Query “原生感知力” —— 深度解析 AppState 与 NetInfo
前端·react native
wordbaby12 小时前
Expo (React Native) 最佳实践:TanStack Query 深度集成指南
前端·react native
wordbaby12 小时前
Expo (React Native) 本地存储全攻略:普通数据与敏感数据该存哪?
前端·react native
冰冷的bin16 小时前
【React Native】渐变骨架屏组件SkeletonElement
react native
wordbaby17 小时前
React Native 安全指南:如何打造“防弹”应用
前端·react native
wordbaby17 小时前
React Native 网络请求完全指南:从 Fetch 到 WebSocket
前端·react native
wordbaby17 小时前
React Native 手势响应系统详解:触摸事件是如何被“瓜分”的?
前端·react native
wordbaby17 小时前
React Native 交互终极指南:搞定触摸与手势 (Handling Touches)
前端·react native
wordbaby18 小时前
React Native 样式系统详解:与 Web CSS 的“似是而非”
前端·react native
wordbaby18 小时前
React Native 图片机制深度解析:设计哲学、性能优化与避坑指南
前端·react native