React-Navigation基础知识
React Navigation在App中创建导航结构
Web浏览器中,可以通过a链接到不同的页面,当用户按下后退按钮,浏览器从访问记录堆栈中弹出项目
RN无法像浏览器一样管理访问路由,需要通过React Navigation实现
React Navigation的本机堆栈导航器为App提供一种在屏幕之间转换和管理导航历史记录的方法
Android上,React Navigation挂钩到硬件后退出,并goBack()在用户按下它时触发该功能
将参数传递给路由
- 通过该参数放入对象中作为函数的第二个参数传递给路由 navigation.navigate: navigation.navigate('RouteName',
- 读取屏幕组件中的参数:route.params
Note: 传递的参数是JSON可序列化的,这样可以使用状态持久性,并且屏幕组件将具有用于实现深度链接的正确契约
<Button color="success" onPress={() => { navigation.navigate( 'Details', { itemId: 86, otherParam: 'anything you want here!' } ) }}>
初始参数
可以将一些初始参数传递到屏幕,在导航到此屏幕上未指定任何参数时生效
在prop上指定initialParams
<Stack.Screen name='Details' component={DetailScreen} initialParams={{ itemId: 42 }} />
参数回传
navigation.navigate({ name: 'Home', params: { post: postText }, merge: true });
参数内容规范
- 错误案例(反模式)
// Don't do this navigation.navigate('Profile', { user: { id: 'jame', firstName: 'Jane', lastName: 'Done', age: 25, } });
这是一种反模式,可以能会导致显示过时数据
更好的方法是参数中仅仅传递用户ID
navigation.navigate('Profile', {userId: '80a808sda808ds0812'}
规范案例
1. ID, eg: 用户ID、项目ID等,eg: navigation.navigate('Profile', { userId: 'Jane'}) 2. 当存在一个项目列表的时候,用于排序、过滤数据等的参数, eg: navigation.navigate('Feeds',{ sortBy: 'latest'}) 3. 时间戳、页码或分页光标, eg: navigation.navigate('Chat', { beforeTime: 435612089}) 4. 用于填充屏幕上输出以组成某些内容的数据, eg: navigation.navigate('ComposeTweet', {title: 'Hello World!'})
★ 将App数据和导航状态分开
传递给函数的参数options是具有一下属性的对象:
- navigation - 屏幕的导航道具
- route - 屏幕的路线道具
更新 options setOptions
/* Inside of render() of React class */ <Button title='Update the title' onPress={() => navigation.setOptions({ title: 'Updated!'})} />
调整标题
自定义标题样式需要使用三个关键属性:headerStyle、headerTintColor和headerTitleStyle
- headerStyle: 将应用于View包装标题样式对象
- headerTintColor: 后退按钮和标题都使用此属性作为颜色,
- headerTitleStyle: 自定义标题样式 fontFamily、fontWeight等样式Text属性
function StackScreen() { return ( <Stack.Navigator name='Home' component={HomeScreen} options={{ title: 'My Home', headerStyle: { backgroundColor: '#3ab09e' }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, }} > </Stack.Navigator> ) }
实现options在多个screen页面共享
<Stack.Navigator screenOptions={{ headerStyle: { backgroundColor: '#f4511e', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, }} > <Stack.Screen name="Home" component={HomeScreen} options={{ title: 'My home' }} /> </Stack.Navigator>
headerTitle提供组件而不是title那样?headerTitle是一个特定于标题的属性而title将用于选项卡栏、抽屉等
默认headerTitle为Text显示title
headerRight 使用带有处理程序的按钮来更新onPress,该处理程序可以访问组件的状态并可以更新它
嵌套导航器
嵌套导航器意味着在另一个导航器的屏幕内渲染另一个导航器
function Home() { return ( <Tab.Navigator> <Tab.Screen name='Feed' component={Feed}/> <Tab.Screen name='Message' component={Message}/> </Tab.Navigator> ) } function App() { return ( <NavigationContainer> <Stack.Navigation> <Stack.Screen name="Home" component={Home} options={{ headerShown: false}} /> <Stack.Screen name="Profile" component={Profile}/> <Stack.Screen name="Settings" component={Setting}/> </Stack.Navigator> </NavigationContainer> ) } * Stack.Navigator - Home(Tab.Navigator) - Feed(Screen) - Message(Screen) - Profile(Screen) - Settings(Screen)
嵌套导航的最佳实践
将嵌套导航器减少到最少,尽可能少的嵌套来实现想要的行为
- 可能会导致深度嵌套的视图层次结构,可能会导致低端设备中的内存和性能问题
- 嵌套相同类型的导航器(eg: 选项卡、抽屉)导致用户体验混乱
- 如果嵌套太多,当导航到嵌套屏幕、配置深层链接的时候,代码会变得难以理解
将嵌套导航器视为实现所需的UI的一种方式,而不是组织代码的一种方式
<Stack.Navigator> { isLoggedIn ? ( // Screens for logged in users <Stack.Group> <Stack.Screen name="Home" component={Home}/> <Stack.Screen name="Profile" component={Profile}/> </Stack.Group> ) : ( // Auth screens <Stack.Group screenOptions={{ headerShown: false }}> <Stack.Screen name="SignIn" component={SignIn}/> <Stack.Screen name="SignUp" component={SignUp}/> </Stack.Group> ) } {/* Common modal screens */} <Stack.Group screenOptions={{ presentation: 'modal'}}> <Stack.Screen name="Help" component={Help}/> <Stack.Screen name="Invite" component={Invite}/> </Stack.Group> </Stack.Navigator>
导航生命周期
使用一个具有两个屏幕(Home和Details)的堆栈导航器并学习如何使用navigation.navigate('RouteName')在路线之间导航
可以通过监听focus和blur事件分别了解屏幕何时进入焦点或失焦
function Profile({ navigation }) { React.useEffect(() => { const unsubscribe = navigation.addListener('focus', () => { // Screen was focused // Do sth... }); }, [navigation]); return <ProfileContent/> }
useFocusEffect可使用钩子来执行副作用,而不是手动添加事件监听器,就像React的useEffect钩子
它和导航生命周期相关
import { useFocusEffect } from '@react-navigation/native'; function Profile() { useFocusEffect( React.useCallback(() => { // Do sth when the screen is focused // Useful for cleanup functions }, []) ); return <ProfileContent/>; }
根据屏幕是否聚焦来渲染不同的内容,可以使用useIsFocused返回一个布尔值来指示屏幕是否聚焦的钩子
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具