ReactNative 详解(三) 基础内容之小技巧

前面两篇已经介绍完了 ReactNative 的基础内容:视图,手势等。基本页面开发应该就没问题了,本章我们介绍下 ReactNative 剩下的一些小技巧。

InteractionManager 交互管理器

想想我们在 js 中,为了保证交互动作,动画的流畅,就需要避免同时存在 js 密集执行的情况。在前端,我们一般不太好把握这个尺度。在前端延迟手段:

  1. requestAnimationFrame():放到下一帧去做,一般绘制动画用
  2. setTimeout(): 在稍后执行代码,不好把控时间
  3. requestIdleCallback():浏览器空闲时间处理,这个看着还不错。但是开启和结束的时间,有浏览器自行决定

在 RN 中,提供了一个 Interactionmanager 可以将一些耗时较长的工作安排到所有互动或动画完成之后再进行。这样可以保证 JavaScript 动画的流畅运行。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Index extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
v: {
width: 50,
height: 50
}
}
}
runAnimate = () => {
// 只有在动画结束后才会触发
InteractionManager.runAfterInteractions(() => {
console.log('动画结束了');
});
LayoutAnimation.linear();
this.setState({
v: {
width: 200,
height: 200
}
});
}
render() {
return (
<View>
<View style={[{backgroundColor: '#ff0000'}, this.state.v]}></View>
<Button title="运行动画" onPress={() => {this.runAnimate()}}/>
</View>
)
}
}

我们也可以通过手动控制执行的时机:
在开始的时候创建句柄,只有手动清除句柄后,才会执行 runAfterInteractions

1
2
3
4
5
let handle = InteractionManager.createInteractionHandle();
// 执行动画... (`runAfterInteractions`中的任务现在开始排队等候)
// 在动画完成之后开始清除句柄:
InteractionManager.clearInteractionHandle(handle);
// 在所有句柄都清除之后,现在开始依序执行队列中的任务

ScrollView && FlatList

ScrollView

ScrollView 类 Android 中的 ScrollView,会简单粗暴地把所有子元素一次性全部渲染出来。但是不适合长列表渲染。

常用属性如下:

  • showsVerticalScrollIndicator:true|false,表示是否显示垂直滚动条;
  • horizontal:true|false,表示滚动方向,true表示横向滚动,false表示竖向滚动。
  • refreshControl:指定RefreshControl组件,用于为ScrollView提供下拉刷新功能,只能用于垂直视图。
  • scrollEnabled:当值为 false 则禁止滚动

常用方法如下:

  • onScrollBeginDrag:当用户开始拖动此视图时调用此函数。
  • onScroll:在滚动的过程中,每帧最多调用一次此回调函数。调用的频率可以用scrollEventThrottle属性来控制。(滚动距离:event.nativeEvent.contentOffset.x,event.nativeEvent.contentOffset.x)
  • onScrollEndDrag:当用户停止拖动此视图时调用此函数
  • scrollTo():滚动到指定的x, y偏移处。第三个参数为是否启用平滑滚动动画

FlatView

类似Android中的ListView或RecyclerView。和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。
FlatList组件必须的两个属性是data和renderItem,data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。
(详细使用可以参考文档)