Skip to content

【React-Native】学习记录 #5

@famousczm

Description

@famousczm

开发过程中学习到的RN小技巧,记录下来(持续更新...)

1. 重置路由

登录成功后进入主页,不能通过返回键(Android)或者侧滑(IOS)回到登录页,方法是跳转页面时使用

navigation.replace('Login')

替换登录页面
当在某个页面点击退出登录按钮退出到登录页时,不能通过返回键或侧滑回到原来的页面或者其他需要登录才能进去的页面,这时当路由栈比较深时用 replace 也不行,必须重置路由栈,重新导入登录页,方法:

import { NavigationActions, StackActions } from 'react-navigation'
...
const resetAtion = StackActions.reset({
        index: 0,
        actions: [
          NavigationActions.navigate({ routeName: 'Login' }), // 要跳转到的页面名字
        ],
})
navigation.dispatch(resetAtion)

2. 询问权限

当APP需要一些如相册、相机、定位、麦克风等系统功能时,需要用户授权或者引导用户去开启相应权限,IOS需要用户去设置那里去手动授权,Android第一次可以立即授权,以后要手动去设置。我常用的组件是:react-native-permissions,使用很简便,具体设置见:点我

IOS需要在 info.plist 中增加相应的 key (Privacy - ...) 和使用说明。

我的操作一般是先 Permission.request(type) 显示请求权限对话框,如果用户未授权,则执行 Permission.check() 返回用户的权限状态并弹出自定义弹框引导用户设置,具体代码:

Permissions.request(type).then((res) => {
      if (res !== 'authorized') {
        Permissions.check(type).then((e) => {
          if (e !== 'authorized') {
            // Alert to set permissions, Permissions.openSettings()
          } else {
            //
          }
        })
      } else {
        //
      }
})

3. setState 与 render

学习 React 的时候知道每次 state 或 props 的改变都会触发组件的 render,那么如果多次执行 setState 的话就会 render 多次呢。

例子:组件有两个状态 a 和 b,如果:

this.setState({ a: 1, b: 1 })

这样 render 了一次,但如果:

this.setState({ a: 1 })
this.setState({ b: 1 })

经测试结果也只 render 了一次,原由是 render 方法是被异步调用的,所以可以保证同步的多个 setState 方法只会触发一次 render。如果是:

this.setState({ a: 1 }, () => {
  this.setState({ b: 1 })
})

就会 render 了两次,开发的时候要注意一下这种影响性能的问题,对于那些不用更新UI的状态或变量,就不需要放在 state 中了。

4. key属性与性能的关系

最近看了一篇关于虚拟DOM Diff 算法的文章,受益匪浅,记录一下,文章链接

开发过程中经常在控制台看到大量的警告日志,内容大多是关于没有给节点绑定唯一的 key。由于程序能正常跑为了避免出其它岔子所以往往都选择忽视,而这往往就导致了 APP 出现性能问题。这是由于虚拟 DOM 更新界面的机制问题,每次 rende 都会对比虚拟 DOM 和 实际 DOM 树之间的差异来更新指定差异的节点,从而提高性能。这其中的比较算法就是 DOM Diff 算法。

key 属性用于标识节点,能够方便DOM Diff 算法去比较,举个例子:A节点下有 B 和 C 两个子节点,现在交换 B 和 C 两节点位置,DOM Diff 算法如何去比较和更新?如果 BC 节点没有设置 key 属性,则算法会认为交换位置后的节点组件类型不同,所以会把 B 和 C 两个节点全删掉再创建;而如果 BC 节点设置了 key 属性,则算法能够知道两节点只是交换了位置,只需要简单的互换位置操作就可以了,大大提高了性能。所以在开发中不能忽视 key 的作用,当涉及到改变 DOM 的操作,最好加上 key 值

5. FlatList 的 onEndReached 问题

使用 FlatList 来渲染一些分页数据的时候,通过 onEndReached 来实现上拉加载的功能,当渲染的组件高度超过屏幕大小时是没有问题的,但当渲染组件数量过少得时候,FlatList 的高度小于屏幕高度,就会频繁触发 onEndReached,导致数据不正确。

目前的解决方法是触发 onEndReached 时判断当前数据是否少于每页数据,如果是就不请求下一页的内容。这样能较好的解决问题。

这个问题搭配 keyExtractor 是许多恶魔级 bug 诞生的原因

6. Android 状态栏 在 Modal 状态下不隐藏的问题

使用 react-native-modal 组件的时候,背景是黑色透明的,就顶部的状态栏是亮的,很碍眼。目前发现较好的解决方法是使用 react-native-modal-translucent

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions