Rn-刷新组件Render(重新渲染)的三种方式详解

开发过游戏的都应该很清楚,“刷屏”是多么的重要。其实开发应用也如此,当组件的数据被修改后,如何及时更新组件呈现出最新的数据与效果一样至关重要。

那么这里Himi大概讲三种常用的方式:

this.setState() 【最为常用】

这是在事件处理函数中和请求回调函数中触发 UI 更新的主要方法。

一般情况下setState() 总是触发一次重绘,除非在 shouldComponentUpdate() 中实现了条件渲染逻辑。如果使用可变的对象,但是又不能在 shouldComponentUpdate() 中实现这种逻辑,仅在新 state 和之前的 state 存在差异的时候调用 setState() 可以避免不必要的重新渲染。

constructor(props) {
    super(props);
    this.state = {
                myName:'I am MyName!',
testFun(){
    this.setState({myName:'组件被刷新了'});
render() {
        .  .  .
        <TouchableHighlight 
          underlayColor='#4169e1'
          onPress={this.testFun.bind(this)}  
            <Image 
            source={require('./res/himi.png')} 
            style={{width: 70, height: 70}} 
        </TouchableHighlight>
        ......
  • 在this.state中添加了一个 字符串变量 myName 用于Text 组件的文字显示
  • 自定义了一个 testFun 函数,用于 Touchable的回调处理,其中调用了this.setState 函数并修改了myName的数据
  • 在render中添加了一个高亮触摸组件,用于演示效果。
    【注】假如有 a、b、c三个组件,b 是 a 的子组件,c是 b 的子组件,那么 b 中 setState 之后,b 和 c 会 rerender,而 a 不会。 因此建议大家可以把每个组件提供一个重绘接口,然后提供给其他组件调用。
    效果如下:(点击查看动态效果)

    如果 render() 方法从 this.props 或者 this.state 之外的地方读取数据,你需要通过调用 forceUpdate() 告诉 React 什么时候需要再次运行 render()。如果直接改变了 this.state,也需要调用 forceUpdate()。
    调用 forceUpdate() 将会导致 render() 方法在相应的组件上被调用,并且子级组件也会调用自己的 render(),但是如果标记改变了,那么 React 仅会更新 DOM。通常情况下,应该尽量避免所有使用 forceUpdate() 的情况,在 render() 中仅从 this.props 和 this.state 中读取数据。这会使应用大大简化,并且更加高效。
    举例、在上面的示例代码基础上修改,如下:

    testFun(){
        this.state.myName='组件被刷新了';
      testForceFun(){
        this.forceUpdate();
    render() {
             . .  .
             <TouchableHighlight 
              underlayColor='#4169e1'
              onPress={this.testFun.bind(this)}  
                <Image 
                source={require('./res/himi.png')} 
                style={{width: 70, height: 70}} 
            </TouchableHighlight>
            <TouchableHighlight 
              underlayColor='#4169e1'
              onPress={this.testForceFun.bind(this)}  
                <Image 
                source={require('./res/himi.png')} 
                style={{width: 40, height: 40}} 
            </TouchableHighlight>
           . . .  .
    

    改动说明:
    a) 修改 testFun 函数,让其作用只是修改了 myName 的值,并没有setState!所以不重绘
    b) 添加 testForceFun 函数,作用是调用强制重绘函数。
    c) render中多加了一个按钮,来触发 testForceFun函数。
    运行效果图如下:(注意 testForceFun 函数对应的是图片较小的那个哦~ )