简单谈下 Component和PureComponent的区别

介绍

React.PureComponent 与 React.Component 几乎完全相同,但 React.PureComponent 通过propsstate的浅对比来实现shouldComponentUpate()

首先按照字面意思:

  1. Component 翻译为中文:组件
  2. Pure,翻译为中文:纯净的,干净的
  3. PureComponet,意思就是 纯净的、干净的组件,简称纯组件

在PureComponent中,如果包含比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断,导致界面得不到更新。

如果定义了 shouldComponentUpdate(),无论组件是否是 PureComponent,它都会执行shouldComponentUpdate结果来判断是否 update。如果组件未实现 shouldComponentUpdate() ,则会判断该组件是否是 PureComponent,如果是的话,会对新旧 props、state 进行 shallowEqual 比较,一旦新旧不一致,会触发 update。

浅对比:通过遍历对象上的键执行相等性,并在任何键具有参数之间不严格相等的值时返回false。 当所有键的值严格相等时返回true。

首先说一下区别

PureComponent自带通过props和state的浅对比来实现 shouldComponentUpate(),而Component没有这个功能的。

然后说一下PureComponent缺点

可能会因深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate结果返回false,界面得不到更新。

再说下PureComponent优势

不需要开发者自己实现shouldComponentUpdate,就可以进行简单的判断来提升性能。

为什么PureComponent比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断?

JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。如 foo={a: 1}; bar=foo; bar.a=2 你会发现此时 foo.a 也被改成了 2。

为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。

下面我们写一个组件来举例子吧

class ChildComponents extends React.PureComponent {
  render() {
    return(
      <div>
        {this.props.sum}
      </div>
    )
  }
}
class ContentComponent extends React.Component {
  constructor(props) {
    super(props); 
    this.state = {
      sum: [0]
    }
  }
  handleChangeSum=()=> {
    const arr = this.state.sum;
    arr.push(1);
    this.setState({
      sum: arr
    })
    console.log(this.state.sum)
  }
  render() {
    <div>
      <button onClick={this.handleChangeSum} />
      <ChildComponents sum={this.state.sum}/>
    </div>
  }
}

我们在ContentComponent 中去修改sum时,ChildComponents 并没有得到刷新。原因在于js使用的是引用赋值,新的对象简单引用了原始对象,改变新对象虽然影响了原始对象,但对象的地址还是一样,使用===比较的方式相等。而在PureComponent中,会被判定prop相等而不触发render()。

避免此类问题最简单的方式是,避免使用值可能会突变的属性或状态,而是使用赋本来返回新的变量。

handleChangeSum() {
  this.setState(prevState => ({
    sum: [...prevState.sum, 'TwoSum'],
  }));
};

另外一种方式是使用Immutable.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值