一、React的渲染机制
要掌握一两项React-render优化的方法不难,但是非常重要.无论是在实际项目中的一个小细节,还是迎合'面试官'的口味
1.1 触发Render
我们知道React要更新视图,必须要触发Render.而这往往是影响性能最重要的一步(因为操作了dom).而React之所以这么出色,正是因为占其主导地位的diff算法采用了虚拟DOM(React V-dom),使得渲染性能大大提升。
即便如此,我们在开发的时候也应该要注意一些性能的优化,比如避免无意义的render
那么,触发render的条件有哪些呢?
- 首次加载组件
- 使用了setState(更新了Props)
- Props更新了(父级传给子级的值改变了)
我们完全可以避免2.3情况导致的一些性能问题
1.2 React Diff
虽然说React高效的Diff算法完美结合了虚拟DOM,让用户可以'无限制'刷新而不需要考虑任何性能问题.
但diff算法还是需要一定的时间,如果你不在意触发render的细节,项目模块大了起来,自然就会影响性能了.
1.3 不做任何优化的例子
我尝试着从实现以下功能:
- 不更新state的值,但是调用了
setState方法 - 传给子级的值不改变,即子级props实际上是没变化的
// 父级.js import React from 'react' import MockChild from './child/index.js' export default class Demo5 extends React.Component{ constructor(args){ super(args) this.state = { 'mockNum': 0 } } handleClick(){ this.setState({ 'mockNum': 0, }) } render(){ console.log('父级state ==============>', this.state) return( <div> <button onClick={this.handleClick.bind(this)}>点击</button> <MockChild mockNum={this.state.mockNum}/> </div> ) } } //子组件 render(){ console.log('子级Props =============>', this.props) return( <div></div> ) }我们反复点击按钮,虽然state的值并没有任何变化,但是我们看打印的结果!

render重复渲染了!
可能会疑问,我在项目并不会做这么一种无用功的!但实际上,当一个组件逻辑复杂起来之后,会产生各种各样的情况.比如:
比如一个组件的中有个包含onChange事件的input,当我改变该输入框内容的时候调用了setState,渲染视图的时候也会触发子组件的重新render.但我们明明没有做任何和子组件有联系的操作
例如上面的例子:
//父组件.js state = { 'mockValue': '123' } handleChange(e){ this.setState({ 'value': '123', }) } //render <input onChange={this.handleChange.bind(this)} /> <MockChild /> /* * 子组件不做变化 */
很不爽,真的!必须给安排掉.

二、基础的React优化
2.1 生命周期: shouldComponentUpdate
可能没听过shouldComponentUpdate,我们简单介绍一下它的执行周期

不熟悉React生命周期的可以看看这篇文章:《React生命周期执行顺序详解》
可以看到它是在render渲染之前触发的,只要我们在这里加以判断就可以有效阻止'无用'的render触发.当然你说
