环境配置
- "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介绍
略
设计思路
我把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