React框架运行机制

React,框架,机制,运行 · 浏览次数 : 86

小编点评

**React框架运行主流程** 1. **JSX转换**:JSX转换为 React.creatElement()方法,返回的是一个虚拟 DOM。 2. **render() 方法**:将虚拟 DOM渲染到真实 DOM的方法,使用 ReactDom.render()。 3. **生命周期方法**:组件的更新通过调用 `setState()` 方法,生成一个新的 VMDom,新 VMDom 与旧的 VMDom相比,生成一个差异对象,然后遍历差异对象,更新真实 Dom。 4. **更新路径**:组件的更新路径有两条: - 父组件主动触发的更新,走上面那条线,会调用 `componentWillReceiveProps()` 方法。 - 组件内部的 state 状态变化触发的更新,走右边那条组件自更新路线。 5. **公共路线**: - `shouldComponentUpdate()` 方法:用于判断是否需要进行刷新,返回 `false` 不进行刷新。 - `componentWillUpdate()` 方法:用于处理状态更新后和 DOM 渲染后回调。 6. **组件卸载**:组件的卸载只有一条方法的调用:`componentWillUnmount()`,用于清理组件相关资源。 **虚拟 DOM 与 Diff 算法虚拟 DOM** - **虚拟 DOM**:一个 js 对象,包含 React 中描述元素的结构。 - **Diff 算法**:用于比较两个 DOM 之间的差异,生成差异对象。 - **虚拟 DOM 的生成**:根据 state 信息和jsx,在 `render()` 方法中创建虚拟 DOM。 - **diff 生成**:使用 `diff()` 方法将新虚拟 DOM 与旧虚拟 DOM 进行对比,生成差异对象。 - **DOM 更新**:将新差异对象渲染到真实 DOM 上。

正文

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。
 
 
 
 

与React框架运行机制相似的内容:

React框架运行机制

React框架运行主流程 1.JSX是JS语言的扩展,被babel编译后,会转换成React.creatElement(),这个方法返回的是一个虚拟DOM。 2.将虚拟DOM渲染到真实DOM的方法是ReactDom.render()。 在React的组件生命周期中,render是灵魂,它创建一个虚拟

nestjs入门学习总结(三):集成typeorm并实现一个curd操作

### typeorm熟悉 TypeORM 是一个ORM框架,它可以运行在 NodeJS、Browser、Cordova、PhoneGap、Ionic、React Native、Expo 和 Electron 平台上,可以与 TypeScript 和 JavaScript (ES5,ES6,ES7,

带你揭开神秘的javascript AST面纱之AST 基础与功能

在前端里面有一个很重要的概念,也是最原子化的内容,就是 AST ,几乎所有的框架,都是基于 AST 进行改造运行,比如:React / Vue /Taro 等等。 多端的运行使用,都离不开 AST 这个概念。在大家理解相关原理和背景后,我们可以通过手写简单的编译器,简单实现一个 Javascript 的代码编译器,编译后在浏览器端正常运行。

ReactNative原理与核心知识点

React Native特点 跨平台 使用js写出页面组件代码被React框架统一转成Virtual DOM树,Virtual DOM树是UI结构的一层抽象,可以被转换成任何支持端的UI视图。 ReactNative框架将Virtual DOM 转成原APP的UIView树。 热修复 ReactNa

京东云开发者|关于“React 和 Vue 该用哪个”我真的栓Q

一、前言:我全都要 面对当今前端界两座大山一样的主流框架,React和Vue,相信很多小伙伴都或多或少都产生过这样疑问,而这样的问题也往往很让人头疼和犹豫不决: 业务场景中是不是团队用什么我就用什么? 如果选择了其中一个使用,那为什么不用另一个? 这两个框架各有什么优点和无法解决的问题? 最新版本的

Java与React轻松导出Excel/PDF数据

前言 在B/S架构中,服务端导出是一种高效的方式。它将导出的逻辑放在服务端,前端仅需发起请求即可。通过在服务端完成导出后,前端再下载文件完成整个导出过程。服务端导出具有许多优点,如数据安全、适用于大规模数据场景以及不受前端性能影响等。 本文将使用前端框架React和服务端框架Spring Boot搭

想让你的工作轻松高效吗?揭秘Java + React导出Excel/PDF的绝妙技巧!

**前言** 在B/S架构中,服务端导出是一种高效的方式。它将导出的逻辑放在服务端,前端仅需发起请求即可。通过在服务端完成导出后,前端再下载文件完成整个导出过程。服务端导出具有许多优点,如数据安全、适用于大规模数据场景以及不受前端性能影响等。 本文将使用前端框架React和服务端框架Spring B

达到学习前端的一种心流状态

我是一名本科应届生,如今在武汉的一家技术公司做前端开发,想必很多人也跟我一样学历不是很高,但是对前端开发有着一腔热血,也可以说是热爱,我没有太多资格来议论关于开发技术上的种种困难点,我分享是对前端学习的一种心境。 我学习前端已经有三年的时间了,前端主流框架Vue,React,Node也都成为了我生活

vue和react的相同点和不同点

Vue和React作为现代前端开发中流行的两个JavaScript框架,它们有诸多相似之处,同时也存在一些关键性的不同。以下是Vue和React的一些主要相同点和不同点: 相同点: 虚拟DOM:Vue和React都使用虚拟DOM(Virtual DOM)来提高性能,减少直接操作真实DOM的频率,从而

Vue 框架下提升加载速度的一些实战经验分享

现在前端的框架有很多,甚至两只手已经数不过来,当然也完全没必要全部都学,还是应该深入的学习一两个被广泛使用的就好。其实我和大部分同学的想法一致,认为最值得我们深究的还是主流的 Vue 和 React。我们通过深入的学习了解这些框架的思维,也让自己使用这些框架能够更加得心应手。