react组件性能优化:
1. 减轻state :只存储跟组件渲染有关的数据 (比如:count / 列表数据 / loading等),是需要变化的数据;不用做渲染的数据不要放在state中, 比如定时器id等。 对于需要在多个方法中用到的数据,应该放在this中
2. 避免不必要的重新渲染
组件更新机制:父组件更新会引起子组件也被更新。但是如果子组件没有发生过任何变化,子组件也会被重新渲染。这样就没有必要进行子组件渲染了。
如何解决这一个问题?使用钩子函数shouldComponentUpdate(nextProps, nextState)
作用:通过返回值决定该组件是否重新渲染,返回true 表示重新渲染,false 表示不重新渲染。
例:
Class Hello extends Component {
shouldComponentUpdate(){
// 根据条件,决定是否重新渲染组件
return false
}
render() { … }
}
触发时机:更新阶段的钩子函数,组件重新渲染前执行 ( shouldComponentUpdate -> render )
可以使用state 阻止组件更新,也可以使用props 阻止组件更新。
例:
class Hello extends Component {
shouldComponentUpdate(nextProps,nextState){
return nextState.num !== this.state.num
}
render () { … }
}
class Hello extends Component {
shouldComponentUpdate(nextProps,nextState){
return nextProps.num !== this.props.num
}
render () { … }
}
3. 纯组件
纯组件: PureComponent 与 React.Component 功能类似
区别:PureComponent 内部自动实现了shouldComponentUpdate 钩子,不需要手动比较
原理: 纯组件内部通过分别对比前后两次 props 和 state 的值,来决定是否重新渲染组件。
说明:纯组件内部的对比是 shallow compare ( 浅层对比 )
对于值类型来说: 比较两个值是否相同 ( 直接赋值即可,没有坑 )
对于引用类型来说:只比较对象的引用(地址)是否相同
注意:state 或 props 中属性值为引用类型时,应该创建新数据,不要直接修改原数据!
// 正确,创建新数据
const newObj = { …state.obj, number: 2 }
setState({ obj: newObj })
// 正确, 创建新数据
// 不要用数组的push / unshift 等直接修改当前数组的方法
// 而应该用 concat 或 slice 等这些返回新数组的方法
this.setState({
list: [ … this.state.list, { 新数据 } ]
})