****关键字 | setState | JSX语法转换 | 组件更新机制

组件更新机制

  • setState() 的两个作用

    • 修改state
    • 更新组件
  • 过程:父组件重新渲染时,也会重新渲染子组件,但只会渲染当前组件子树(当前组件以其所有子组件)

组件性能优化

减轻state
  • 减轻state:只存储跟组件渲染相关的数据(比如:count/ 列表数据 /loading等)
  • 注意:不用做渲染的数据不要放在state中
  • 对于这种需要在多个方法中用到的数据,应该放到this中
避免不必要的重新渲染
  • 组件更新机制:父组件更新会引起子组件也被更新,这种思路很清晰
  • 问题:子组件没有任何变化时也会重新渲染
  • 如果避免不必要的重新渲染?
  • 解决方式:使用钩子函数 shouldComponentUpdate(nextProps, nextState)
    • 在这个函数中,nextProps和nextState是最新的状态以及属性
  • 作用:这个函数有返回值,如果返回true,代表需要重新渲染,如果返回false,代表不需要重新渲染
  • 触发时机:更新阶段的钩子函数,组件重新渲染前执行(shouldComponentUpdate => render)
// 生成随机数
class RandomNumber extends React.Component {
state = {
number: 0
};
btnHandlerClicked = () => {
this.setState((state, props) => {
return {
number: Math.ceil(Math.random() * 3)
}
})
}; // 两次生成的随机数可能相同,如果相同就没必要重新渲染
// 将要更新UI的时候会执行这个钩子函数
shouldComponentUpdate(nextProps, nextState, nextContext) {
console.log('nextProps: ',nextProps ,' -- nextState: ' , nextState , ' -- nextContext' , nextContext , ' -- this.state', this.state);
if(nextState.number !== this.state.number || nextProps.sendnumber !== this.props.sendnumber){
return true;
}
return false;
} render() {
console.log('render -- ');
return (
<div>
<h2>随机数: {this.state.number}</h2>
<button onClick={this.btnHandlerClicked}>clickedMe create random number</button>
</div>
)
}
} // 渲染
ReactDOM.render(<RandomNumber/>, document.getElementById('root'));

纯组件

作用以及使用
  • 纯组件: PureComponent 与 React.Component 功能相似

  • 区别: PureComponent 内部自动实现了 shouldComponentUpdate钩子,不需要手动比较

  • 原理:纯组件内部通过分别比对前后两次 props和state的值,来决定是否重新渲染组件

    // 生成随机数
    class RandomNumber extends React.PureComponent {
    state = {
    number: 0
    };
    btnHandlerClicked = () => {
    this.setState((state, props) => {
    return {
    number: Math.ceil(Math.random() * 3)
    }
    })
    }; render() {
    console.log('render -- ');
    return (
    <div>
    <h2>随机数: {this.state.number}</h2>
    <button onClick={this.btnHandlerClicked}>clickedMe create random number</button>
    </div>
    )
    }
    } // 渲染
    ReactDOM.render(<RandomNumber sendnumber={1234}/>, document.getElementById('root'));
实现原理
  • 说明:纯组件内部的对比是 shallow compare(浅层对比)
  • 对于值类型来说:比较两个值是否相同
  • 引用类型:只比对对象的引用地址是否相同
  • 注意:state 或 props 中属性值为引用类型时,应该创建新数据,不要直接修改原数据
// 正确做法:创建新对象
const newObj = { ...this.state.obj, number: Math.floor(Math.random() * 3) }
this.setState(() => {
return {
obj: newObj
}
}) // 错误演示:直接修改原始对象中属性的值
const newObj = this.state.obj;
newObj.number = Math.floor(Math.random() * 3) this.setState(() => {
return {
obj: newObj
}
})

最新文章

  1. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变
  2. ORA-20011 ORA-29913 and ORA-29400 with Associated KUP-XXXXX Errors from DBMS_STATS.GATHER_STATS_JOB(Doc ID 1274653.1)
  3. SharePoint 2013 关于自定义显示列表表单的bug
  4. 【caffe】未定义函数或变量caffe_
  5. Windows资源管理器 已停止工作
  6. ES6中的const命令
  7. oracle 设置标识列自增
  8. 第一个js程序
  9. 多校第五场 归并排序+暴力矩阵乘+模拟+java大数&amp;amp;记忆化递归
  10. 示例:Netty 处理 TCP数据分包协议
  11. 配置国内PIP源方法
  12. 如何用ABP框架快速完成项目(6) - 用ABP一个人快速完成项目(2) - 使用多个成熟控件框架
  13. Spring Day 1
  14. 用asp.net core 把用户访问记录优化到极致
  15. wtforms源码流程
  16. ModelAttribue注解的使用
  17. windows命令快捷启动应用-----window小技巧
  18. CPU缓存一致性协议与java中的volatile关键字
  19. [翻译] GTAppMenuController
  20. 史上最简单的SpringCloud教程 | 第九篇: 服务链路追踪(Spring Cloud Sleuth)(Finchley版本)

热门文章

  1. 启用Executor初始化线程池
  2. [HDU3072]:Intelligence System(塔尖+贪心)
  3. Make jQuery throw error when it doesn&#39;t match an element
  4. sensu
  5. Linux_系统时间管理
  6. 一:flask-第一个flask程序
  7. excel 字母变大写 宏
  8. Linux mysql ERROR 1045 解决
  9. Jmeter---后置处理器 BeanShell PostProcessor 获取JDBC结果(多行)并以列表传入另一个请求
  10. 11.metasploit辅助模块----基本Exp----ARP欺骗中间人MITM----WordPress破解