- 减少render函数里 新建的变量、函数
- 减少render函数里的大量计算
- 减少给子组件传递的props
- bind函数在constructor里执行
- 定制 shouldComponentUpdate 函数
- v16之后 如果组件只是根据传进来的props进行渲染,没有内部的状态,可以使用 React.PureComponent
// 默认父组件 render函数执行了 子组件也会render
// shouldComponentUpdate(nextProps,nextState) 是父组件render 或者本身 setState时候或执行的函数
// 他决定当前组件是否应该重新render, 当父组件重新render时,子组件未接收到改变的props时避免渲染
// shouldComponentUpdate 可以通过对两个对象 nextProps和this.props 做对比,来决定是否重新渲染组件
function shouldComponentUpdate (nextProps,nextState) {
if (nextProps.title === this.props.title) {
retrun false
}
return true
}
// 深递归对比,复杂度太高,不可接受,react建议只做浅层比较,PureComponent也是如此只做浅层比较
// 所以从性能上考虑,建议无论在redux还是state时候,数据结构不要深层次嵌套,因为react无法深比较
// 一但嵌套层次过深,react会总是更新组件,造成性能隐患
不可变得数据结构:
- 减少内存使用
- 并发安全
- 减少可变带来的复杂度
- 便于比较复杂数据结构,定制shouldComponentUpdate 方便
- 时间旅行功能方便
- 函数式编程,方便写纯函数
immutable缺点:
- 学习成本
- 库的大小
- 对先有项目入侵太严重(新项目可以使用,老项目评估再用)
共享可变的状态是万恶之源:把一个可以修改的状态交给别人,让别人共享是一件很危险的事情
// immutable-js 生成不可变得数据结构:
// 一旦创建不可修改,只能生成新的数据结构,所以直接用等号就可以判断两个数据是否相等
// 对定制 shouldComponentUpdate 生命周期函数,是一个非常好的数据结构,这也是需要immutable-js的原因
import { Map, is } from 'immutable'
constructor {
this.state = Map({
name: 'xxx',
num: 1
})
}
this.setState(this.state.set('num', this.state.get('num') + 1))
<SubComponent name={this.state.get('name')} />
shouldComponentUpdate (nextProps,nextState) {
return is(nextProps, this.props)
}
// reselect:用在重复大计算的时候
// 从redux的state里面获取数据,和获取到的数据经过计算,变成组件可用的数据分成了两步
// 内部会做一些缓存的计算,做重复操作的时候性能会更加好,不用重复计算
import { createSelector } from 'reselect'
const numSelector = createSelector(
state=>state,
state=>({num: state*2}) // 第二个函数的参数,是第一个函数的返回值
)
@connect(
state=>numSelector(state),
{
actionCreator1,
actionCreator2,
actionCreator3
}
)