组件性能优化
纯函数
- 给定相同的输入,它总是返回相同的输出;
- 过程没有副作用(side effect)
- 没有额外的状态依赖
PureRender
PureRender 中的 Pure 指的就是组件满足纯函数的条件,即组件的渲染是被相同的 props 和 state 渲染进而得到相同的结果。
PureRender 本质
官方在早期就为开发者提供了名为 react-addons-pure-render-mixin 的插件。其原理为重新实现了 shouldComponentUpdate 生命周期方法,让当前传入的 props和 state 与之前的作浅比较,如果返回 false ,那么组件就不会执行 render 方法。
运用 PureRender
import React, { Component } from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
class App extends Component {
constructor(props) {
super(props);
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
}
render() {
return <div className={this.props.className}>foo</div>;
}
}
优化 PureRender
- 直接为 props 设置对象或数组
例:
给Account组件设置style prop :<Account style={{ color: 'black' }} />
这样设置 prop,则每次渲染时 style 都是新对象 - 设置 props 方法并通过事件绑定在元素上
import React, { Component } from 'react';
class MyInput extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.update(e.target.value);
}
render() {
return <input onChange={this.handleChange} />;
}
}
不用每次都绑定事件,因此把绑定移到构造器内。如果绑定方法需要传递参数,那么可以考虑通过抽象子组件或改变现有数据结构解决。
- 设置子组件
import React, { Component } from 'react';
class NameItem extends Component {
render() {
return (
<Item>
<span>Arcthur</span>
<Item />
)
}
}
翻译简化之后:
<Item
children={React.createElement('span', {}, 'Arcthur')}
/>
复杂典例:
import React, { Component } from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
class NameItem extends Component {
constructor(props) {
super(props);
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
}
render() {
return (
<Item>
<span>Arcthur</span>
</Item>
);
}
}