1

【React】PureComponent解决了什么问题]
(转载于https://segmentfault.com/a/11...

PureComponent是和shouldComponentUpdate这个生命周期息息相关的

React 重新渲染问题

React中,当父组件中触发setState, 尽管未修改任何state中的值也会引起所有子组件的重新渲染, 更何况是修改了某个state

还有, 当父组件传给子组件的props发生改变, 不管该props是否被子组件用到, 都会去重新渲染子组件。

其实我们也可以想得到, setState 会去触发 render, 所以父组件render函数中的子组件都会被重新渲染, 因此也就无关stateprops

针对这个问题我实现了个例子, 来看一下下面这个例子

实现下问题

setState但未修改任何state

父组件触发setState方法, 但未更新任何state

import TodoItem from './components/todoItem/todoItem'
// 父组件代码
class TodoList extends Component {
  noChange() {
    console.log('触发setState')
    this.setState(() => ({
    }))
  }
  render() {
    const { todoList } = this.state
    return (
      <div className="wrap">
        <button onClick={() => this.noChange()}>没有变化的setState</button>
        {
          todoList.map( (item,index) => <TodoItem key={index}  data={item} /> )
        }
      </div>
    )
  }
}

// 子组件代码
class TodoItem extends Component {
  constructor(props) {
    super(props)
  }

  componentWillUpdate() {
    console.log('我被更新了')
  }

  render() {
    return (
      <div>
        { this.props.data.thing }
      </div>
    )
  }
}

我们在子组件中预留了componentWillUpdate方法, 用来监测子组件是否被跟新

componentWillUpdate() {
  console.log('我被更新了')
}

实验结果:

noChangeState

我们可以看到, 每一次的点击都引起了子组件的update

冷静分析问题

无故的重复update, 这会导致业务规模扩大后十分的影响性能.

为此我监测了一下页面的重绘事件:

绿色区域是浏览器发成重绘的地方

noRePaint

可以看到todoList其实并没有引起浏览器的repaint, 因此可以推测, 实际dom并没有更新这在渲染页面前被dom diff给排除掉了, 因此性能损耗在了转换成Virtual DOM的过程中

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState), 默认返回true

shouldComponentUpdateReact中做性能优化的重要手段, 看这个英文翻译我们大概也能猜出个一二来 --- '组件是否跟新?'

React会根据shouldComponentUpdate的返回结果来决定该组件是否重新渲染, 如果返回True就渲染, 如果返回False就重新渲染

基于这个特性, 我们来修改一下上面问题中的代码

// 父组件无变化, 因此省略

// 子组件代码
class TodoItem extends Component {

  // ...省略其他原有的代码


  // --------- 新增代码 -------------
  shouldComponentUpdate(nextProps, nextState) {
    // 判断下 当前 props传入的data.thing  是否和新传入的  data.thing 相同
    return  this.props.data.thing !== nextProps.data.thing
  }
  // --------- 新增代码 -------------
}

实验结果:
addShouUpdate

我们可以看到update事件确实消失了

PureComponent

看了shouldComponentUpdate函数的作用, 就能够理解PureComponent了? 它其实就是在帮我们做这样一件事:

自动的帮我们编写shouldComponentUpdate方法, 避免我们为每个组件都编写一次的麻烦

我们只需要这样, 就可以一步到位

import React, { PureComponent } from 'react'
class TodoItem extends PureComponent {
}

云端的日子
66 声望1 粉丝