React Native和Typescript的项目开发入门

React Native

React是前端三大框架之一,React Native是它在两大客户端平台(IOS和Android)上的实现,react-dom则是浏览器(包括服务端渲染)上的实现,所以说React Native的地位与react-dom对应,依赖于React,他们间有版本依赖关系。

样式布局

React Native由于客户端的实现,样式的写法也有所不同。正常样式的写法没法对RN有效,官方利用Flexbox(弹性盒子)语法通过yoga实现了对页面进行布局,区别在于默认是纵向,并非横向。细节以下:

  • 主要分为ViewStyle和TextStyle两类,不能交叉使用
  • Images必须定高宽
  • 样式不能实现继承,只有text嵌套能继承样式,但是这种情景不多
  • 高宽采用数字,默认单位为dp,会导致ios和安卓不统一的情况

样式适配

移动端的样式问题一直是非常关键的问题,移动端H5页面是通过rem(或者vw)来进行适配的。RN由于默认是以dp为单位,乘以dpr才得到实际像素。举个栗子,有两台手机,分别是iphone 7(宽度 3752),小米9SE(宽度3603)。这时候如果我在RN中设置360,ios则显示不全。说明如果设计稿是按照375进行设计的话,需要进行一个简单的换算。

RN的样式问题

拿当前屏幕的宽度和设计稿宽度得出换算比例,封装成转换函数即可。

import { Dimensions } from 'react-native';
const defaultWidth = 375;
export let screenW = Dimensions.get('window').width;
const _scaleWidth = screenW / defaultWidth;

export function scaleSize(size: number): number {
    return size * _scaleWidth;
}

纯RN应用还是混合RN应用

纯RN应用还是混合RN应用是两个大方向,取决于你的团队大小和公司规模。它们主要有以下这些区别:

纯RN应用 混合RN应用
性质 业务逻辑都在RN 客户端支持
跳转方式 RN内部跳转 支持Native,H5,RN跳转
入口 单一页面入口 多个页面入口
优点 逻辑统一 定制程度高
缺点 首屏时间长 依赖于客户端的版本

expo 框架未来的发展方向更多是“大而全”的设计模式,它属于纯RN应用,包含了react-native-svgreact-native-vector-icons等开源库,如果你的目标是做一款纯RN应用,没有其他的客户端同事参与,则应该考虑使用expo。特殊的Native定制应该从expo插件的方向出发。

expo react-native-cli
没有ios和android文件夹 有ios和android文件夹
能expo client调试 调试较为麻烦
自带native环境(可eject) 需要自行配置
提供发布工作流 需要自行打包和热更新的机制

混合RN应用则是以“小而美”作为标准,后续的版本RN将会继续执行Lean Core Removals的政策。一些非核心的部分会交给社区(react-native-community)管理,侧面也看出社区的重要性。RN60后,webview netinfo 和 geolocation将会被移除出react native仓库,交给社区管理。精简过后的RN更加具有粘性和生命力,同时也更适合用于混合RN应用。

客户端将native代码和RN代码的混合,在保证核心页面性能的情况下,可以将多变或容易出错的页面可以交给前端同事完成,并实现灵活的热更新服务。

Typescript

typescript大家应该已经不陌生,但是如何将RN和typescript以及babel结合,提高开发效率,增加项目的可维护性。

Eslint

随着tslint的没落,结合eslint强大生态圈,eslint和typescript的结合成为未来的方向。最重要引入的肯定是react-native-community社区提供的规则@react-native-community/eslint-config以及react-native的plugin,有效规避代码里面不符合RN生态的写法。

@typescript-eslint/parser则是用于ts的解析工作。

module.exports = {
  // eslintrc.js
  env: {
    browser: false,
    es6: true,
  },
  extends: ['@react-native-community', 'plugin:prettier/recommended'],
  globals: {
    Atomics: 'readonly',
    SharedArrayBuffer: 'readonly',
  },
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: 'module',
  },
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint', 'react-native'],
};

Babel

由于RN的打包是使用metro.js,所以很多webpack的技巧,我们没法使用,让很多所谓高级前端工程师触手可及。因此,babel的插件成为了关键点。巧妙的使用babel插件能够提高开发效率。

这里推荐两款babel插件。

环境变量的引入可以有效将变量抽离,提高代码的维护性。还有很多babel插件等待大家的挖掘。

参考

题外话

shopee,又称虾皮,是一家腾讯投资的跨境电商平台。这里加班少,技术氛围好。如果想和我并肩作战一起学习,可以找我内推。邮箱weiping.xiang@shopee.com,非诚勿扰。