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

相关推荐
_一两风12 小时前
深入理解 React 事件机制与 DOM 事件系统
react native·react.js
Misha韩1 天前
React Native 初始化项目和模拟器运行
react native
Misha韩3 天前
React Native 亲切的组件们(函数式组件/class组件)和陌生的样式
react native·函数式组件·class组件
1234Wu3 天前
React Native 接入 eCharts
javascript·react native·react.js
wen's4 天前
React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
javascript·react native·react.js
朝阳394 天前
ReactNative【实战系列教程】我的小红书 3 -- 自定义底栏Tab导航(含图片选择 expo-image-picker 的使用)
react native
冰冷的bin4 天前
【React Native】自定义倒计时组件CountdownView
react native
朝阳3914 天前
React Native【实用教程】(含图标方案,常用第三库,动画,内置组件,内置Hooks,内置API,自定义组件,创建项目等)
react native
朝阳3915 天前
React Native【实战范例】同步跟随滚动
react native
朝阳3916 天前
React Native【详解】动画
react native