来学习怎么使用 React Native 吧!
新建项目
项目按运行台分为 ios 和 android,其中 ios 只能在 macOS 上开发,所以对于 windows 玩家,只能玩玩 android 了(
- 安装 Android Studio 并配置 - 请根据 官方文档 进行该步骤 
- 创建 rn 项目 - 如果你之前全局安装过旧的 - react-native-cli命令行工具,请使用- npm uninstall -g react-native-cli卸载掉它以避免一些冲突
- 在项目父目录,执行 - 1 - npx react-native init AwesomeProject - 以新建名为 - AwesomeProject的 rn 项目- 也可以使用 - --template来使用一些社区提供的模板,例如带有- TypeScript配置的:- 1 - npx react-native init AwesomeTSProject --template react-native-template-typescript 
 
- 在 Android Studio 中打开项目下的 android 目录,然后通过 - Tools/AVD Manager选项,打开虚拟机页面- 如果没有虚拟机,需要点击 - Create Virtual Device...,创建新的虚拟设备,并在选择需要的设备类型后,在- Recommended选项卡中选择 Q API Level 29 image,Target 选择 android 10.0
- 确保虚拟机已经启动后,在项目根目录运行命令提示符,然后 - yarn android即可启动 app
注意,命令提示符会打开一个新的 node 命令窗口,在该窗口键入 Ctrl+C 需要连续两次才可退出,或键入 R 以重载应用
基建
RN默认是只有
- 根目录- android
- ios
- __tests__
- 比宇宙更重的 node_modules
 
这样几个文件夹的,其余文件比如 App.tsx 都是放在根目录下
那我们就要先按 react 编码习惯,给目录做个层级
于是新建一个 src 目录来放置我们的代码
我弄成了如下结构
| 1 | --root | 
同时,rn 默认是:
- 不支持 less
- 不能直接 use svg
- 不能直接使用 redux
所以必须要先配置一下
less
使用 react-native-less-transformer 插件
github 地址:https://github.com/kristerkari/react-native-less-transformer
安装依赖
| 1 | yarn add --dev react-native-less-transformer less | 
打开 metro.config.js,向其中的 transformer  加入 babelTransformerPath: require.resolve("react-native-less-transformer"),向resolver 加入 "less"
文件大致变为如下模样
| 1 | const {getDefaultConfig} = require('metro-config'); | 
现在就可以在 tsx 文件中引入 less 文件了
| 1 | import styles from './index.less' | 
但是,还是不能做到像 umi 中的 less 一样的效果,具体来说,嵌套不能用了,我很难过(
不过可以装 vscode 插件 CSS Modules 来做到对 tsx 中的 style 引用的快速定位
iconfont
使用 react-native-iconfont-cli 插件来解决该问题
github 地址:https://github.com/iconfont-cli/react-native-iconfont-cli
安装依赖
| 1 | yarn add react-native-svg | 
然后静态链接
| 1 | react-native link react-native-svg | 
最后生成配置文件
| 1 | npx iconfont-init | 
此时项目根目录会生成一个 iconfont.json 的文件,内容如下:
| 1 | { | 
参数意义如下
| 参数 | 意义 | 
|---|---|
| symbol_url | iconfont 官网提供的 [symbol].js 的地址 | 
| use_typescript | 如果使用 ts 开发,最好设置为 true,但即便是 false,也会提供 .js和.d.ts两种文件,来提供支持 | 
| save_dir | 存放图标文件的地址,每次生成组件之前,该文件夹都会被清空 | 
| trim_icon_prefix | 去除统一前缀 | 
| default_icon_size | 默认大小 | 
| local_svgs | 本地 svg 的路径,如无可以填空字符串 | 
于是我的 iconfont.json 长这样
| 1 | { | 
配置完成后,开始生成组件
| 1 | npx iconfont-rn | 
组件生成后,可以通过如下办法使用
| 1 | import Icon from '../src/iconfont'; | 
通过 name 来指定要使用的 icon,并可以通过 size 按需调整大小
当你在 iconfont 上选择了新图标后,要更新配置文件里的 symbol_url 并重新生成图标文件
redux
直接使用 redux 和 react-redux
| 1 | yarn add react-redux redux | 
装完就可以用了
先在 ./src/store 中创建 index.ts
然后声明 actions
| 1 | const actions = ['user/info'] as const;type ActionType = typeof actions[number]; | 
这样使得我们在使用 ActionType 可以使用自动代码补全
之后创建 StateType 用以描述 state
| 1 | interface StateType { | 
再创建 reducer 来进行数据更改的提交
| 1 | function reducer( | 
reducer 接受两个参数,分别是:
- state,表示 redux 当前的状态
- action,是一个包含 type和payload两个字段的对象,表示传入的操作
然后我们通过 switch 来根据传入的不同 type 进行不同的操作
在 reducer 中直接 return xxx 将会覆盖现在的 state,所以记得先展开原有的 state
最后一步,创建 store 对象,并暴露给外部使用
| 1 | const store = createStore(reducer); // import {createStore} from 'redux'; | 
然后在 App.tsx 上使用 <Provider> 进行包装
| 1 | import {Provider} from 'react-redux'; | 
现在可以在外部使用 connect 来连接数据了
| 1 | import {View, Text} from 'react-native'; | 
connect 接收两个参数
- mapStateToProps,是一个函数,该函数接收 redux 的 state 作为参数,并返回一个对象,在向下传递时,会将该对象解构并赋值到组件的 props上
- mapDispatchToProps,也是一个函数,该函数接收 redux 提供的提交动作 dispatch作为参数,并该函数返回一个对象,在向下传递时,会将该对象解构并赋值到组件的props上
connect 执行完毕后悔返回一个新函数,新函数接收一个函数组件作为参数,并将上述返回值解构并赋值到组件的 props 上。同时,外部传入的组件原本的 props 也会保留
注意,直接引入 store 并使用其 getState 方法来获得 state 的话,实质上并没有订阅 state 的更新,所以 state 更新时并不会触发视图的重新渲染,因此建议在除 <Provider> 外的任何地方,均使用 connect 来完成 state 的订阅
antd
原生的 input 不好用,所以需要 antd
但也只有文本框用 antd 方便了(
文档:https://rn.mobile.ant.design/docs/react/introduce-cn
安装依赖
| 1 | yarn add @ant-design/react-native | 
链接
| 1 | react-native link @ant-design/icons-react-native | 
按需加载
在项目根目录创建 .babelrc 文件,并写入如下内容
| 1 | { | 
就可以正常使用 antd 了
感谢阅读