首页 > 其他分享 >React框架运行机制

React框架运行机制

时间:2023-01-31 23:55:06浏览次数:60  
标签:count 框架 DOM React 组件 state 运行机制 setState

React框架运行主流程 1.JSX是JS语言的扩展,被babel编译后,会转换成React.creatElement(),这个方法返回的是一个虚拟DOM。 2.将虚拟DOM渲染到真实DOM的方法是ReactDom.render()。   0 在React的组件生命周期中,render是灵魂,它创建一个虚拟Dom;生命周期方法是躯干,负责事件的承载。 组件挂载 1.constructor()初始化state数据 2.componentWillMount() 3.render() 4.componentDidMount() 0   组件的更新 通过调用setState,生成一个新的VMDom, 新的VMDom与旧的VMDom相比,生成一个差异对象,然后遍历差异对象,更新真实Dom。 组件的更新路径有两条: 如果是父组件主动触发的,走上面那条线,会调用componentWillReceiveProps() 如果是组件内部的state状态变化触发的,走右边那条组件自更新路线。 公共路线: 1.shouldComponentUpdate() 2.componentWillUpdate() 3.render() 4.componentDidUpdate() 0   组件的卸载 组件的卸载只有一条方法的调用: 1.componentWillUnMount() 0   setState更新数据机制 1.setState是异步任务更新的,所以在setState后面做同步数据获取拿到的数据是之前的值。 2.连续调用多次setState,只会触发一次重新渲染,原因是React内部会合并连续的setState调用,提高刷新性能。 连续两次this.setState,同步获取的this.state.count是没有修改前的,连续2次的this.setState是无效的,在更新前会做合并,只有一次是有效的。

console.log("更新前:",this.state.count)
this.setState({
  count: this.state.count + 1
})
console.log("更新后1:",this.state.count)
this.setState({
  count: this.state.count + 1
})
console.log("更新后2:",this.state.count)
推荐使用第二种 通过传入箭头函数,拿箭头函数中的state参数,此参数表示最新的state值,所以虽然下面的 this.setState是异步方法,但是连续的2次调用,对state的修改是有序的,最终的结果是修改2次的结果
//state:最新的状态,props:最新的props
this.setState((state, props)=>{
  return {
    count: state.count + 1
  }
})
console.log("更新后1:",this.state.count)
this.setState((state, props)=>{
  return {
    count: state.count + 1
  }
})
console.log("更新后2:",this.state.count)
this.setState的第二个参数是回调函数,表示在状态更新完成后并且DOM渲染完成后,立即回调。
this.setState({
  count: this.state.count + 1
},() => {
  console.log("状态更新后,DOM页面渲染后:", this.state.count)
})

 

JSX的转换流程   0   1.代码中用jsx写的ele元素
const ele = <h2 id={"title"}>标题</h2>
2.被babel转换器转换后的React语句
React.createElement("h2", {id:"title"}, React.createContext("标题"))
3.React底部对ele元素的底层实现,是一个简单的js对象
$$typeof: Symbol(react.element)
key: null
props: 
    children: "标题"
    id: "title"
    [[Prototype]]: Object
    ref: null
type: "h2"
_owner: null
_store: {validated: false}
_self: undefined
_source: {fileName: '/Users/zhoufei/Documents/React/web/my-app/src/my-src/Principle.js', lineNumber: 5, columnNumber: 13}
[[Prototype]]: Object

 

React的UI刷新机制 setState会触发刷新,触发流程分2步 1.更新状态数据 2.刷新UI 第二步的刷新UI是局部递归刷新的。 比如点击了页面中的子组件B,那么只会在子组件B和其子孙组件触发UI刷新,其他的兄弟组件和父组件是不刷新的。 0 React组件性能优化 1.减轻state 2.组件避免不必要的刷新 减轻state state的修改会触发渲染,如果变量与渲染无关,那么就不要放在state中,放到this的成员变量中就可以了。 比如创建一个定时器,将定时器id放到this.timerID上。 组件避免不必要的刷新 根据组件的刷新机制,如果父组件刷新,那么它里面的所有子组件,子孙组件都要进行刷新,对于状态没有修改的情况下,重复刷新是浪费性能。可以在下面的方法判断是否需要进行刷新。 shouldComponentUpdate(nextProps, nextState, nextContext),返回false不进行刷新。 1.父组件内,判断this.state.count === nextState.count
shouldComponentUpdate(nextProps, nextState, nextContext) {
  //this.state: 之前的状态
  //nextState: 后面要修改的状态
  if (this.state.count === nextState.count) {
    return false
  } else {
    return true
  }
  
  //优化
  //return this.state.count !== nextState.coun
}
2.子组件内判断this.props.count !== nextProps.count
class Child extends React.Component{
  shouldComponentUpdate(nextProps, nextState, nextContext) {
    return this.props.count !== nextProps.count
  }

  render() {
    return (
        <div>
          子组件入参计数:{this.props.count}
        </div>
    );
  }
}
3.使用纯组件React.PureComponent替换React.Component PureComponent内部会自动实现方法shouldComponentUpdate,并对state和props分别比较,相同的话就返回false,取消渲染。
class PureChild extends React.PureComponent{
  render() {
    console.log("纯子组件 render")
    return (
        <div>
          纯子组件入参计数:{this.props.count}
        </div>
    );
  }
}
纯组件中的对比采用的是shallow compare,浅对比,如果是基本类型就是直接进行对比,如果是引用类型就对比其内存地址对比。 所以,如果是要对比对象或数组,那么就用...解包新建一个,这样会有新的内存地址。
class PureChild extends React.PureComponent{
  state = {
    obj: {
      count: 0
    },
    list: [
        "jack"
    ]
  }
  
  hanleClick = () => {
      //对象,数组的对比要采用新建的方式
    this.setState({
      count: {...this.state.obj, count: 1},
      list: [...this.state.list, "lucy"]
    })
  }
  
  render() {
    console.log("纯子组件 render")
    return (
        <div>
          纯子组件入参计数:{this.props.count}
        </div>
    );
  }
}

 

虚拟DOM与Diff算法 虚拟DOM:是一个js对象,用来描述你希望展示到屏幕上的内容。 0 虚拟DOM和Diff算法一起渲染流程: 1.根据state信息和jsx,在render后共同组成了一个虚拟DOM。 2.然后将虚拟DOM渲染render,变成真实的DOM。 3.当state信息变化时,React会生成一个新的VM DOM。 4.将新旧VM DOM进行对比,生成差异对象。 5.遍历差异对象,将差异对象更新到真实的DOM上。   0 render方法调用并不是说会刷新这个DOM树,而是生成了一个新的虚拟DOM,要开始diff了。 然后再将新生成的VM DOM与旧的VM DOM对比找到修改的差异对象,然后将这个差异对象渲染到屏幕上。 虚拟DOM的价值 虚拟DOM的最大价值不是让渲染性能更高了,而是让React脱离了浏览器的真实DOM而存在 只要能执行js的地方,都可以运行React。 所以React是面向虚拟DOM编程的,它可以将虚拟DOM根据不同的平台转换成不同的真实DOM。 IOS,安卓转换成原生控件,浏览器转换成页面标签。 Vue的虚拟DOM思想就是借鉴了React的虚拟DOM。        

标签:count,框架,DOM,React,组件,state,运行机制,setState
From: https://www.cnblogs.com/zhou--fei/p/17081211.html

相关文章

  • react官方文档-高级部分-Render Props学习(重要)
    前言:术语“renderprop”是指一种在React组件之间使用一个值为函数的prop共享代码的简单技术 具有renderprop的组件接受一个函数,该函数返回一个React元素并......
  • django框架之drf(部分讲解)
    restful规范(重要)一、概念REST全称是RepresentationalStateTransfer,中文意思是表述:表征性状态转移,它首次出现在2000年RoyFielding的博士论文中。RESTful是一种定义W......
  • Gin框架实战——HTML渲染
      最近使用Go的Gin框架做了个简单的前端网页,记录一下细节~1.加载静态文件    由于网页需要使用css、图片等渲染,而静态文件必须先声明:否则模板中调用加载不出......
  • django框架之drf:2、restful规范,序列、反序列化,drf安装及使用(django原生接口及drf接口
    Django之drf一、restful规范1、概念​ REST全称是RepresentationalStateTransfer,中文意思是表述:表征性状态转移,它首次出现在2000年RoyFielding的博士论文中。​ R......
  • Yolov4的框架理解
                                                        ......
  • Yolov3的大致框架理解
                                                       ......
  • 10个高效的Python爬虫框架
    前言小型爬虫需求,requests库+bs4库就能解决;大型爬虫数据,尤其涉及异步抓取、内容管理及后续扩展等功能时,就需要用到爬虫框架了。(文末送读者福利)下面介绍了10个爬虫框架,大......
  • 框架串讲二
    SpringMvcSpringMvc注解有哪些:@RestController@RequestMapping@PostMapping@DeleteMapping@PutMapping@GetMapping@PathVariable@RequestParam@RequestBody@Re......
  • 混合式APP开发框架
    在企业移动战略布局中,app已成为连接业务与用户最主要的载体,同样其开发技术目前也处于十分成熟的阶段。随着软件技术的日新月异的更新换代,基于原生开发的移动端越来越没落。......
  • react 高效高质量搭建后台系统 系列 —— 系统布局
    其他章节请看:react高效高质量搭建后台系统系列系统布局前面我们用脚手架搭建了项目,并实现了登录模块,登录模块所依赖的请求数据和antd(ui框架和样式)也已完成。本篇将......