减轻 state
- 减轻 state : 只存储组件渲染相关的数据 ( 比如 : count / 列表数据 / loading 等)
- 注意: 不用做渲染的数据不要放在 staet 中 , 比如定时器 id 等
- 对于这种需要在多个方法中用到的数据 , 应该放在this中
避免不必要的重新染
- 组件更新机制: 父组件更新会引起子组件也被更新 , 这种思路很清晰
- 问题: 子组件没有任何变化时也会重新渲染
- 如何避免不必要的重新渲染
- 解决方法: 使用钩子函数 shouldComponentUpdate(nextProps , nextState)
- 作用: 通过返回值决定组件是否重新渲染 , 返回 true 表示重新渲染 , false 表示不重新渲染
- 触发时机: 更新阶段的钩子函数 , 组件重新渲染钱执行 ( shouldComponentUpdate => render )
class Hello extends React.Component {
shouldComponentUpdate() {
// 根据条件 , 决定是否重新渲染组件
return false
}
render() {... }
}
nextState : 最新的 state
this.state : 更新前的state
可以用if判断 来返回true 或 false
纯组件
- 纯组件: PureComponent 与 React.Component 功能相似
- 区别: PureComponent 内部自动实现了 shouldComponentUpdate 钩子 , 不需要手动比较
- 原理: 纯组件内部通过分别 对比 前后两次 props 和 state 的值 , 来决定是否重新渲染组件
- 说明: 纯组件内部的对比是 shallow compare ( 浅层对比 )
- 对于值类型来说: 比较两个值是否相同 ( 直接赋值即可 , 没有坑)
- 对于引用类型来说: 只比较对象的引用(地址)是否相同
- 注意: state 或 props 中属性值为引用类型时 , 应该创建新数据 , 不要直接修改元数据!
虚拟 DOM 和 Diff 算法
- React 更新视图思想: 只要state 变化就重新渲染识图
- 特点: 思路清晰
- 问题: 组件中只有一个 DOM 元素需要更新时 , 也得把整个组件的内容渲染到页面中
- 理想状态: 部分更新 , 只更新变化的地方
- 通过:虚拟 DOM 和 Diff 算法
虚拟 DOM : 本质上就是一个 JS 对象 , 用来描述你希望在屏幕上看到的内容
- 初次渲染时 , React 会根据state ( Model ) , 创建一个虚拟DOM对象树
- 根据虚拟 DOM 生成真正的DOM , 渲染到页面中
- 当数据变化后( setState() ) , 重新根据新的数据 , 创建新的虚拟DOM对象(树)
- 与上一次得到的虚拟 DOM 对象 , 使用 Diff 算法 对比 (找不同), 得到需要更新的内容
- 最终 , React 只将变化的内容更新 ( patch ) 到 DOM 中 , 重新渲染到页面
示例:
组件 render () 调用后 , 根据 状态 和 JSX结构 生成虚拟DOM对象