React Native 之 setNativeProps

在React Native 中,改变组件的布局样式等可以通过props或者state来实现,但由于性能瓶颈,我们不得不放弃通过触发render的方式来改变样式,而是通过setNativeProps来直接更改原生组件的样式属性来达到相同的效果。

这里的setNativeProps方法等价于直接操作DOM节点的方法。使用这种方法修改View、Text等react Native自带的组件,并且不会触发组件的componentWillReceivePropsshouldComponentUpdatecomponentWillUpdate 等组件生命周期中的方法。但它不应该经常被使用,一般建议在不得不频繁刷新而又遇到了性能瓶颈时使用。建议在使用此方法之前优先考虑setState和shouldComponentUpdate方法来解决问题。

setNativeProps 与 TouchableOpacity

TouchableOpacity这个组件就在内部使用了setNativeProps方法来更新其子组件的透明度:

setOpacityTo: function(value) {
  // Redacted: animation related code
  this.refs[CHILD_REF].setNativeProps({
    opacity: value
  });
},

由此我们可以写出下面这样的代码:子组件可以响应点击事件,更改自己的透明度。而子组件自身并不需要处理这件事情,也不需要在实现中做任何修改。

<TouchableOpacity onPress={this._handlePress}>
  <View style={styles.button}>
    <Text>Press me!</Text>
  </View>
</TouchableOpacity>

如果不使用setNativeProps这个方法来实现这一需求,那么一种可能的办法是把透明值保存到state中,然后在onPress事件触发时更新这个值:

getInitialState() {
  return { myButtonOpacity: 1, }
},

render() {
  return (
    <TouchableOpacity onPress={() => this.setState({myButtonOpacity: 0.5})}
                      onPressOut={() => this.setState({myButtonOpacity: 1})}>
      <View style={[styles.button, {opacity: this.state.myButtonOpacity}]}>
        <Text>Press me!</Text>
      </View>
    </TouchableOpacity>
  )
}

比起之前的例子,这一做法会消耗大量的计算 —— 每一次透明值变更的时候React都要重新渲染组件结构,即便视图的其他属性和子组件并没有变化。一般来说这一开销也不足为虑,但当执行连续的动画以及响应用户手势的时候,只有正确地优化组件才能提高动画的流畅度。

将setNativeProps传递给子组件

具体要做的就是在我们的自定义组件中再封装一个setNativeProps方法,其内容为对合适的子组件调用真正的setNativeProps方法,并传递要设置的参数。

var MyButton = React.createClass({
  setNativeProps(nativeProps) {
    this._root.setNativeProps(nativeProps);
  },

  render() {
    return (
      <View ref={component => this._root = component} {...this.props}>
        <Text>{this.props.label}</Text>
      </View>
    )
  },
});

这里我们使用了ref回调语法,我们向下传递props时使用了{...this.props}语法,(这一用法的说明请参考对象的扩展运算符),这是因为复合组件除了要求在子组件上执行setNativeProps意外,还要求子组件对触摸事件进行处理,因此会传递多个props.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 8,104评论 2 35
  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,860评论 1 18
  • 前言 本文 有配套视频,可以酌情观看。 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我讨论。 文中所有内...
    珍此良辰阅读 11,942评论 23 111
  • 溪水在弹奏小鸟在歌唱 花草在跳舞树木是观众 你在其中游走
    心花园子阅读 222评论 0 2
  • 在以十年、二十年、三十年乃至更久的时间尺度上,伴随一饼新茶从青涩到甘醇,从浓烈到敦厚,它陪伴你完成了一生的醇化与升...
    茶雲澗阅读 347评论 0 0