我们可以看到react提供了两种组件的类型,一开始学习的时候都是使用Component,但是React提供了另外一个 PureComponent, 纯组件,目的是: 优化渲染
import React, { Component } from ‘react’;
import React, { PureComponent } from ‘react’;
Component
在React Component的生命周期中,有一个shouldComponentUpdate方法。这个方法默认返回值是true。这意味着就算没有改变组件的props或者state,也会导致组件的重绘。这就经常导致组件因为不相关数据的改变导致重绘,这极大的降低了React的渲染效率。
比如下面的例子中:任何options的变化,甚至是其他数据的变化都可能导致所有cell的重绘。
{this.props.items.map(i =>
<Cell data={i} option={this.props.options[i]} />
)}
为了避免这个问题,我们可以在Cell中重写shouldComponentUpdate方法,只在option发生改变时进行重绘。
class Cell extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
if (this.props.option === nextProps.option) {
return false;
} else {
return true;
}
}
}
在重写方法后 每个Cell只有在关联option发生变化时进行重绘。
PureComponent
因为上面的情况十分通用,React创建了PureComponent组件创建了默认的shouldComponentUpdate行为。这个默认的shouldComponentUpdate行为会一一比较props和state中所有的属性,只有当其中任意一项发生改变是,才会进行重绘。
需要注意的是,PureComponent使用浅比较判断组件是否需要重绘
通俗的说 对于复杂数据类型只会去 比较指针 是否变化。
因此,下面对数据的修改并不会导致重绘(假设Table也是PureComponent)
options.push(new Option())
options.splice(0, 1)
options[i].name = "Hello"
项目中使用PureComponent 注意事项
-
Literal Array与Literal Object {this.props.items.map(i =>
<Cell data={i} options={this.props.options || []} />
)}
若options为空,则会使用[]。[]每次会生成新的Array,因此导致Cell每次的props都不一样,导致需要重绘。解决方法如下: const default = [];
{this.props.items.map(i =>
<Cell data={i} options={this.props.options || default} />
)}
-
内联函数 函数也经常作为props传递,由于每次需要为内联函数创建一个新的实例,所以每次function都会指向不同的内存地址。比如: render() {
<MyInput onChange={e => this.props.update(e.target.value)} />;
}
注意第二个例子也会导致创建新的函数实例。为了解决这个问题,需要提前绑定this指针: constructor(props) {
super(props);
this.update = this.update.bind(this);
}
update(e) {
this.props.update(e.target.value);
}
render() {
return <MyInput onChange={this.update} />;
}
|