总是应该认识一些基本概念
原生组件
在 rn 中不可以使用 html 标签,只能使用 rn 提供的原生组件,或第三方提供的可以用于 rn 的组件
原生组件列表请参看官方链接:https://reactnative.cn/docs/components-and-apis
主要有以下核心组件:
组件名 | 等效 html 标签 | 重要的特殊之处 |
---|---|---|
View | div | 无点击事件 |
Text | span | 所有直接文本必须包裹在 <Text> 之中,包括实体字符 |
Image | img | 必须指明高度和宽度 |
ScrollView | - | ScrollView 不可以嵌套在另一个 ScrollView 中 |
TextInput | input | - |
样式
有了结构,自然要有样式
内联的样式可以直接通过组件的 style
属性进行书写,每个属性使用驼峰写法
注意每个标签可以具有的 style
是不一样的,比如 color
属性,无法设置在 View
组件上(因为 View 不能直接包含文本),只能设置在 Text
组件上
也可以使用内部样式,写法如下
1 | import {StyleSheet} from 'react-native'; |
create 之后的 styles
实质上也还是一个对象,可以通过 styles.container
来使用样式,只不过通过 StyleSheet.create
来创建的话,会有自动代码补全
使用时,直接书写于组件的 style
属性中。注意,react 原本是写于 className
属性中,此处不同
1 | <View style={styles.container}> |
也可以使用 spread 运算符
1 | <View style={{...styles.container, backgroundColor: 'black'}}> |
在上一章中我们引入了 less 支持,所以当然也可以写外部样式
1 | // index.less |
1 | import styles from './index.less' |
之后用法与内部样式一样
基本布局
为了达到类似 caho 的移动端效果,我们需要页脚
则有如下组件
1 | import {SafeAreaView, ScrollView, View} from 'react-native'; |
首先使用 SafeAreaView
作为外层,以做到 ios 支持。详见 https://reactnative.cn/docs/safeareaview
然后使用 ScrollView
包裹主要视图,使得主视图组件可以上下滑动;同时,提供一个自定义的 Footer
组件作为页脚
注意,此处页脚必须写在 ScrollView
外部,才可以固定在视图下部,起到类似于 positon: fixed;
之效果
为什么要这样?因为 rn 的 style 不支持 position: fixed;
如果写在 ScrollView
内部,就会造成必须滚动到页面最下方才可以看到页脚
同时,因为页脚现在类似 fixed
,所以会遮挡掉 ScrollView
最末尾的部分,所以需要在 ScrollView
中放置一个等高的空组件来占位
路由
路由如何配置,是非常重要的一环,必须要了解
设计
参考 Caho,我暂且设置了如下路由
1 | interface Route { |
配置
使用 react-navigation
来实现路由
文档地址:https://reactnavigation.org/docs/getting-started/
安装依赖
1 | yarn add @react-navigation/native @react-navigation/native-stack react-native-screens react-native-safe-area-context |
然后打开 App.tsx
,引入需要的组件
1 | import {NavigationContainer} from '@react-navigation/native'; |
react-navigation
要求我们通过 NavigationContainer
和 Stack
注册路由,之后才可以正常使用
注册写法如下
1 | import router from './router'; |
首先使用 <NavigationContainer>
创建 navigation 容器,然后使用 <Stack.Navigator>
创建路由栈,用于在不同路由之间往返,最后通过 <Stack.Screen>
声明每一个路由
对于每条路由,可以手写,也可以如上这般通过数组遍历来完成,但要注意,<Stack.Navigator>
只接受 <Stack.Screen>
作为直接子级
对于每个 Screen,必要参数有 name
和 component
,用于指示其唯一标识符和要渲染的组件。上例中的 key
是因为数组方法 map
要求对每个组件传入 key
作为唯一标识符
此处的 component
使用了一个包装函数,来使得所有组件共用相同的布局,不需要各自引入页脚
此外,还可以传入 options
来指示路由的标题等内容。上例中传入了 title
作为标题,headerTitleAlign
作为标题的对齐方式,headerRight
作为附加在标题右侧的组件。该标题会渲染在每个页面的最上方,等效顶边栏
现在就完成路由的配置了,启动应用就会发现应用路由到了 initialRouteName
所指示的组件
如果没有指示 initialRouteName
,则会路由到 <Stack.Screen>
列表中的第一个组件
跳转
可是这样只能到达一个页面呀,该怎么前往其它页面呢
可以使用注入的 navigation
对于通过路由到达的每个组件,其 props
中均会被注入一个 navigation
导航器,该导航器具有两个重要方法:
navigate: (navigationName: NavigationName, payload?: any) => void;
,第一个参数是路由名 (name),第二个参数可选,是通过路由传递的参数getState: () => any;
,可以获得上层路由传递过来的参数,包含路由栈内全部的参数
显然,这是归属于路由的功能,但是 react-navigation
不提供 navigation
的类型定义,所以我们可以在 ./src/router/index.ts
中提供我们自己的类型定义
1 | const paths = [ |
通过这样的定义,我们就可以在外部使用 navigation
的使用,声明其类型为 Navigation
,并在其 navigate
方法中使用代码自动补全
然后,我们可以在任意的直接路由到达的组件中,获取 navigation
导航器,例如
1 | // ./src/screen/user/index.tsx |
则从页脚跳转到 /user/[id]
的代码如下
1 | navigation.navigate('/user/[id]', {id: userId}) |
页脚
刚才一直说页脚,它是怎么实现的呢?
其实就是在 View
里面放 Icon
,2333
1 | import React from 'react'; |
注意,此处使用了 onPress
属性,可以认为等效于在写 html 时的 onClick
属性,但是 View
上是没有该属性的,需要使用 TouchableOpacity
等可点击组件,但这是后面的内容了
感谢阅读