****关键字 | 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
}
})

【React 6/100】 React原理 | setState | JSX语法转换 | 组件更新机制的更多相关文章

  1. React的JSX语法及组件

    最近一个同事很急没有做任何交接就请了陪产假,然后我来维护.说实在的我一开始是一脸懵逼的.因为MV*项目里用的最多的还是Vue:React听说也了解过,但毕竟不熟... 不过不管如何这也是工作:同事也恭 ...

  2. react系列(一)JSX语法、组件概念、生命周期介绍

    JSX React中,推出了一种新的语法取名为JSX,它给了JS中写HTML标签的能力,不需要加引号.JSX的语法看起来是一种模板,然而它在编译以后,会转成JS语法,只是书写过程中的语法糖. JSX的 ...

  3. react实战项目开发(2) react几个重要概念以及JSX语法

    前言 前面我们已经学习了利用官方脚手架搭建一套可以应用在生产环境下的React开发环境.那么今天这篇文章主要先了解几个react重要的概念,以及讲解本文的重要知识JSX语法 React重要概念 [思想 ...

  4. react快速上手二(使用JSX语法)

    前提: 下载依赖,配置 cnpm i babel-preset-react -D JSX语法的本质: 还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代 ...

  5. react.js 从零开始(三)JSX 语法及特点介绍

    什么是jsx? jsx = JavaScript + xml jsx 是一种 Ecmascript 的一种新标准. jsx 是一种 带有结构性的语法. jsx 的特点: 1.类xml语法易于理解. 2 ...

  6. React反模式 —— 如何不使用JSX地动态显示组件

    欢迎指导与讨论 : ) 前言 文章的最后能写出以 Modal.open( ) 这种调用形式,动态显示React对话框组件的写法(类似于ant design),同时涉及数据交互(数据能异步地返回给调用者 ...

  7. 【React -- 9/100】 抽离顶部导航栏 - [组件复用]

    今天写的页面中需要重复使用到顶部导航栏,所以把顶部导航栏抽离出来 考虑复用组件的健壮性,使用PropTypes校验,可以自定义一个click事件 JSX import React from " ...

  8. 前端笔记之React(一)初识React&组件&JSX语法

    一.React项目起步配置 官网:https://reactjs.org/ 文档:https://reactjs.org/docs/hello-world.html 中文:http://react.c ...

  9. React实例入门教程(1)基础API,JSX语法--hello world

      前  言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发 ...

随机推荐

  1. 【技术分享:python 应用之二】解锁用 VSCode 写 python 的正确姿势

    之前一直用 notepad++ 作为编辑器,偶然发现了 VScode 便被它的颜值吸引.用过之后发现它启动快速,插件丰富,下载安装后几乎不用怎么配置就可以直接使用,而且还支持 markdown.当然, ...

  2. JavaScript的事件队列(Event Queue)---宏任务和微任务

    前言 在写代码的时候经常思考一个问题,到底是那个函数先执行,本身JavaScript是一门单线程的语言,意思就是按照顺序执行.但是加入一些setTimeout和promise的函数来又实现了异步操作, ...

  3. Redis大key的发现与删除方法全解析

    个推作为国内第三方推送市场的早期进入者,专注于为开发者提供高效稳定的推送服务,经过9年的积累和发展,服务了包括新浪.滴滴在内的数十万APP.由于我们推送业务对并发量.速度要求很高,为此,我们选择了高性 ...

  4. 微信小程序 API 数据缓存

    微信小程序 数据缓存 (类似于 cookie) wx.setStorage() 将数据存储在本地缓存中制定的 key 中.会覆盖掉原来该 key 对应的内容,数据存储生命周期跟小程序本身一致,即除用户 ...

  5. 让DOM元素自动滚到视野内ScrollIntoView

    概述 项目中需要把一个DOM元素自动滚动到视野内,百思不得其解,最后再element库里面发现了这个方法,记录下来供以后开发时参考,相信对其他人也有用. 参考资料:element scroll-int ...

  6. 设置了responseType:Blob之后,如果返回json错误信息,如果获取?

    最近做了一个文件下载功能,于是设置了responseType: Blob的方式, 什么是Blob呢,MDN官方解释:Blob 对象表示一个不可变.原始数据的类文件对象.Blob 表示的不一定是Java ...

  7. vue路由高级用法

    五.路由设置高级用法alias 别名 {path:'/list',component:MyList,alias:'/lists'}redirect 重定向 {path:'/productList',r ...

  8. 最小二乘法公式推导及Python实现

    机器学习使用线性回归方法建模时,求损失函数最优解需要用到最小二乘法.相信很多朋友跟我一样,想先知道公式是什么,然后再研究它是怎么来的.所以不多说,先上公式. 对于线性回归方程\(f(x) = ax + ...

  9. 学了一天的golang从入门到放弃

    Google的go就是个二货,不实用,它最多只能和c比简单.low!

  10. xmake新增对Cuda代码编译支持

    最近研究了下NVIDIA Cuda Toolkit的编译环境,并且在xmake 2.1.10开发版中,新增了对cuda编译环境的支持,可以直接编译*.cu代码. 关于Cuda Toolkit相关说明以 ...