React Native 开发常见问题及注意事项

本文只是使用时积累的一些经验

开发环境

1、Android Studio 依赖项下载慢

如果发现依赖下载非常慢,动不动十几KB的

bash 复制代码
 repositories {
	 // google()
	 // jcenter()
     mavenLocal()
     mavenCentral()
     maven { url 'https://jitpack.io' }
     maven { url 'https://maven.aliyun.com/repository/jcenter' }
     maven { url 'https://maven.aliyun.com/repository/google' }
     maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
     maven { url 'https://maven.aliyun.com/nexus/content/groups/gradle-plugin' }
 }

2、npm install 或 yarn 很慢

主要由于 github 相关的服务在国内速度问题导致,如: canvas 安装慢、安装失败的解决方法等

- npm install 或 yarn 很慢给命令行装上楼梯

bash 复制代码
# proxyOn.bat

set https_proxy=http://127.0.0.1:10809
set http_proxy=http://127.0.0.1:10809
set all_proxy=socks5://127.0.0.1:10808
echo  "Proxy is on.\n" 

- 使用国内镜像的方式加速

给 npm 提供 config 参数 --{module_name}_binary_host_mirror 可以通过镜像下载二进制文件

bash 复制代码
npm install canvas --canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas

缺点是需要在命令行中添加参数,不便于维护。

- 在 npm 配置文件中配置

可以在.npmrc (npm的配置文件) 中设置一个或多个模块的二进制文件下载镜像地址

bash 复制代码
# .npmrc

registry=https://registry.npmmirror.com
# 淘宝 NPM 镜像站切换新域名,老 npm.taobao.org 和 registry.npm.taobao.org 域名
# 于 2022 年 05 月 31 日零时起停止服务,由registry.npmmirror.com域名继续提供服务

# node-sass预编译二进制文件下载地址
sass_binary_site=https://registry.npmmirror.com/-/binary/node-sass
electron_mirror=https://registry.npmmirror.com/-/binary/electron/

# 无特殊配置参考{pkg-name}_binary_host_mirror={mirror}
canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas
node_sqlite3_binary_host_mirror=https://registry.npmmirror.com/-/binary/sqlite3

3、iOS 连接重置问题

如下图:iOS 安装完成后,断连了无法刷新手机设备页面白屏,连接被重置

原因:大概率是手机和Mac不在同一WiFi 网络环境下,请检查设备网络

typescript 复制代码
Socket SO_ERROR [54: Connection reset by peer]

Text 组件

大多数情况下,建议设置 Text 的 lineHeight 样式属性。才能按照设计稿的要求将 Text 放到正确的位置上,在iOS系统中才不会出现兼容性问题。

如果需要设置背景颜色和圆角,建议外层再加一层 View ,不要直接在 Text 组件本身上面设置,因为在 iOS 系统上Text 组件的圆角样式会失效。

Text 是可以嵌套的,这对于需要在同一行文字中,设置不同的大小颜色等,是非常有用的。内层文字会继承外层文字的样式。

typescript 复制代码
<Text style={{ lineHeight: 20, fontSize: 14, color: '#333333' }}>
  同意
  <Text style={{ color: '#448AFF' }}>《协议》</Text>
  !
</Text>

fontWeight 属性可以设置粗体。但是设置为数值时,只对 iOS 生效。

所有显示内容都需要 <text>内容</text> 进行包裹,否则会报错

Text 吞字现象

当你发现,设置了 fontWeight: 'bold',但在部分 Android 手机上,却看不到粗体的效果

那么很有可能发生了吞字现象。Text 组件文字显示不全

当 Text 中的文本同时符合以下两个条件时,在部分 Android 手机上会出现文字显示不全的问题。

  • 含有半角字符(数字、字母、空格、特殊符号)
  • style 设置了 fontWeight 属性,不管它的值是什么

解决参考:https://juejin.cn/post/7127811778620162078

View 组件

View 通常作为容器使用,熟练使用 flexbox 布局,可以让 UI 层级更加简洁。

Flexbox 布局

使用 Flexbox 布局https://reactnative.cn/docs/flexbox#flex

在 React Native 中使用 flexbox 规则来指定某个组件的子元素的布局。Flexbox 可以在不同屏幕尺寸上提供一致的布局结构。

一般来说,使用flexDirection、alignItems和 justifyContent三个样式属性就已经能满足大多数布局需求。

React Native 中的 Flexbox 的工作原理和 web 上的 CSS 基本一致,当然也存在少许差异。首先是默认值不同:flexDirection的默认值为column(而不是row),alignContent默认值为 flex-start(而不是 stretch), flexShrink 默认值为0 (而不是1), 而flex只能指定一个数字值。

onLayout 获取 View 的位置和大小

这个在列表组件中弹窗很有用

@react-native-community/hooks 这个包提供了一个方便的 Hook 来帮助我们获取这些信息。

typescript 复制代码
 import { useLayout } from '@react-native-community/hooks'
 
 function MyComponent() {
    const { x, y, width, height, onLayout } = useLayout()
    return <View onLayout={onLayout} />
  }

Style 样式问题

在 React Native,也会遭遇 1px 分割线的问题,不同的设备上,直接使用 1 px 可能会出现粗细不一样的线

React Native 提供了一个常量来解决这个问题:StyleSheet.hairlineWidth。这个常数将总是一个整数的像素(所以由它定义的线看起来很清晰),并将试图匹配底层平台上细线的标准宽度。

PixelRatio 工具类有个 roundToNearestPixel 方法,可以将数值转换为最接近的整数像素。

如果你发现两个 View 之间有间隙,总是合不拢或者有的粗有的细,就可以尝试使用这个方法。

这个也不是一定可解决的

TextInput 组件

多行文本与顶部对齐

当将 multiline 设置为 true 时,在 iOS 上,文本会与顶部对齐,而在 Andriod 上,则保持垂直居中。需要将 textAlignVertical 设置为 top,才能保持两个平台的表现一致。

在 Android 上,在垂直方向上会有默认的 padding,多行文本下,为了保持两个平台的表现一致,需要将 padding 样式属性设置为 0 或适当的值。

为了保证不同平台的一致性,最好涉及Text 、TextInput 时设置行高lineHeight

两个外层边距保持平行

输入框 borderRadius 内外如果都设置为 12 看上去就边角出就不是平行的

内层的 borderRadius 的值 = 外层的 borderRadius 值 - 两者之间的边距

这样就是平行的了,看上去就会美观很多

热更新

https://pushy.reactnative.cn/docs/faq

1、哪些修改可以热更新?哪些不能?

我们把对应用的修改分为两类:

不可热更新 ------ 原生修改,即所有需要编译后才能生效的修改:

  • 任何在 iOS 或者 Android 目录中的修改、增删。
  • 任何含有原生代码的第三方组件的更新、修改。

可以热更新 ------ 非原生修改,即所有无需编译,刷新即可生效的修改:

  • js 代码修改,包括第三方纯 js 组件的更新、修改。
  • 可以在 js 代码中 require/import 的资源文件,例如图片。

需要注意的是,即便资源文件可以热更新,但这些热更新后的资源文件会以file://协议的形式提供访问,某些读取资源文件的第三方可能并不支持file://协议。

2、热更新成功完成,但是重启后又回滚了是怎么回事?

可以正常更新,但是重启后回滚,一般是没有正确配置 bundleUrl

3、热更新报错:"热更新已暂停,原因:编译时间戳与服务器记录不一致"

当您每次编译产生一个原生包时,其中都会记录一个编译时间戳buildTime(可以使用pushy parseIpa a.ipa或是pushy parseApk a.apk命令来查看)。如果您需要把这个包发给客户并希望使用热更新功能,那么就需要使用 upload 命令来上传到我们的服务器,而服务器端会记录这个包的版本号和编译时间戳以便后续比对记录。

调试日志

通过参数控制输出的数据和格式,灵活应用它会大大提高我们的工作效率。

1、console.log

typescript 复制代码
console.log(url, url2, baz)
// 对比 
console.log({ url, url2, baz })
// 在日志前加上唯一字符串前缀
console.log('debug-log', { url, url2, baz })

在日志前加上唯一字符串前缀是很有用的。这样可以更容易地在控制台中搜索和过滤日志。

2、JSON.stringify

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

语法
JSON.stringify(value[, replacer [, space]])

参数
value

将要序列化成 一个 JSON 字符串的值。
replacer 可选

如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。

space 可选

指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。

typescript 复制代码
  let list = {
    listObj: [
      { name: '张三', age: 18 },
      { name: '李四', age: 20 },
      { name: '王五', age: 22 },
      { name: '赵六', age: 24 },
    ]
  }

  console.log('====================================')
  console.log(JSON.stringify(list))
  console.log('====================================')
  console.log(JSON.stringify(list, null, 1))
  console.log('====================================')
  console.log(JSON.stringify(list, null, 10))
  console.log('====================================')
typescript 复制代码
  const dataArr = [
    {
      name: "person1",
      sex: 0,
      age: 18,
      isStudent: true
    },
    {
      name: "person2",
      sex: 1,
      age: 25,
      isStudent: false
    },
    {
      name: "person3",
      sex: 0,
      age: 15,
      isStudent: true
    }
  ]
typescript 复制代码
  console.log('====================================')
  console.log(JSON.stringify(dataArr, ['name'], 1))

  console.log('====================================')
  const res = JSON.stringify(
    dataArr,
    (key, value) => {
      if (key == 'sex') {
        return ["女", '男'][value];
      }
      return value;
    },
    2
  )
  console.log(res);

只输出姓名

将性别转为中文字符

待续。。。

其他

如果是作为初学者,建议先看官方文档,至少通读一遍,做聪明人下笨功夫,要有 遍历精神

相关推荐
天若有情6738 小时前
程序员原创|借鉴JS事件冒泡,根治电脑文件混乱的“冒泡整理法”
开发语言·javascript·windows·ecmascript·电脑·办公·日常
FYKJ_201010 小时前
springboot校园兼职平台--附源码02041
java·javascript·spring boot·python·eclipse·django·php
沐言人生14 小时前
React Native 源码分析1——HybridData 机制深度分析
android·react native
空中海14 小时前
01 React Native 基础、核心组件与布局体系
javascript·react native·react.js
空中海15 小时前
05 React架构设计、项目实践与专家清单
前端·react.js·前端框架
前端之虎陈随易17 小时前
2年没用Nodejs了,Bun很香
linux·前端·javascript·vue.js·typescript
空中海17 小时前
04 工程化、质量体系与 React 生态
前端·ubuntu·react.js
Yue16817 小时前
一文教你五分钟学会Zustand,React状态管理更加方便!
react native
空中海17 小时前
03 性能、动画与 React Native 新架构
react native·react.js·架构
好运的阿财18 小时前
OpenClaw工具拆解之host_workspace_write+host_workspace_edit
前端·javascript·人工智能·机器学习·ai编程·openclaw·openclaw工具