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

相关推荐
番茄小酱00121 小时前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
少恭写代码2 天前
duxapp放弃了redux,在duxapp中局部、全局状态的实现方案
react native·taro·redux·duxapp
番茄小酱0013 天前
ReactNative中实现图片保存到手机相册
react native·react.js·智能手机
EBABEFAC4 天前
响应式编程-reactor
java·开发语言·react native
Engss8 天前
Taro React-Native Android apk 打包
android·react native·taro
镰刀出海9 天前
RN开发环境配置与Android版本app运行
android·react native
wills77711 天前
Flutter 状态管理框架Get
flutter·react native
MavenTalk11 天前
前端跨平台开发常见的解决方案
前端·flutter·react native·reactjs·weex·大前端
起司锅仔12 天前
ReactNative TurboModule(3)
android·javascript·react native·react.js
起司锅仔12 天前
ReactNative 简述(1)
android·javascript·react native·react.js