为了提升效率努力让努力变的更纯(pure),减少在组件更新周期的重新渲染;
1,使用react-addons-pure-render-mixin或React.PureComponent可以让组件自行判断props(浅层)的变化;帮助我们实现shouldComponentUpdate的控制,减少其他非组件相关数据变化引起的重新渲染;
2,使用了以上内容之后需注意:
(1),直接为 props 设置对象或数组等字面量形式:
如:<Item style={{ color: 'black' }} />
因为每次调用 React 组件其实都会重新创建组件。就算传入的数组或对象的值没有改变,它们引用的地址也会发生改变。
解决方法:在外部定义完变量再引用:const defaultStyle = {}; 尽量使用const;
(2),不能在组件上绑定事件时不能使用以下两种形式:
第一种绑定是因为每次调用时会重新bind(this),导致方法的引用每次都会改变;第二种是每次都会重新生成箭头函数,导致引用改变。
解决方法:在construct里绑定this;
(3),子组件里有子组件:
render() {
return (
<Item>
<span>Arcthur</span>
<Item/>
)
}
}
上面的子组件 JSX 部分翻译过来,其实是:
<Item
children={React.createElement('span', {}, 'Arcthur')}
/>
解决方法:子组件设置 PureRender;
4,尽量使用具体的prop,不使用{...props}等形式;
5,map里面添加key,并且key不要使用index(可变的),尽量使用id等判断。
6,使用 Immutable 进一步提升组件的渲染性能 :
(1),为了保存原状态(刷新或对比时使用)很多时候都会用到浅拷贝或者深拷贝,这个时候会造成 CPU 和内存的浪费,这个时候可以使用Immutable 定义数据,修改数据时不会改变原数据(注意接收返回的新数据),同时Immutable 使用了结构共享(structural sharing),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其他节点则进行共享,所以也不会引起新的效率问题。
(2),使用PureRender时:以上介绍了PureRender官方提供的形式,而Immutable.js 则提供了简洁、高效的判断数据是否变化的方法,只需 === 和 is 比较就能知道是否需要执行 render,而这个操作几乎零成本,所以可以极大提高性能。使用Immutable 级可以更深入的实现,如下:
import { is } from 'immutable';
shouldComponentUpdate(nextProps, nextState) {
const thisProps = this.props || {};
const thisState = this.state || {};
if (Object.keys(thisProps).length !== Object.keys(nextProps).length ||
Object.keys(thisState).length !== Object.keys(nextState).length) {
return true;
}
for (const key in nextProps) {
if (nextProps.hasOwnProperty(key) &&
!is(thisProps[key], nextProps[key])) {
return true;
}
}
for (const key in nextState) {
if (nextState.hasOwnProperty(key) &&
!is(thisState[key], nextState[key])) {
return true;
}
}
return false;
}