前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >react源码解析5.jsx&核心api

react源码解析5.jsx&核心api

原创
作者头像
用户9002110
发布于 2021-12-04 01:32:50
发布于 2021-12-04 01:32:50
40900
代码可运行
举报
运行总次数:0
代码可运行

react源码解析5.jsx&核心api

视频讲解(高效学习):进入学习
virtual Dom是什么

一句话概括就是,用js对象表示dom信息和结构,更新时重新渲染更新后的对象对应的dom,这个对象就是React.createElement()的返回结果

virtual Dom是一种编程方式,它以对象的形式保存在内存中,它描述了我们dom的必要信息,并且用类似react-dom等模块与真实dom同步,这一过程也叫协调(reconciler),这种方式可以声明式的渲染相应的ui状态,让我们从dom操作中解放出来,在react中是以fiber树的形式存放组件树的相关信息,在更新时可以增量渲染相关dom,所以fiber也是virtual Dom实现的一部分

为什么要用virtual Dom

大量的dom操作慢,很小的更新都有可能引起页面的重新排列,js对象优于在内存中,处理起来更快,可以通过diff算法比较新老virtual Dom的差异,并且批量、异步、最小化的执行dom的变更,以提高性能

另外就是可以跨平台,jsx --> ReactElement对象 --> 真实节点,有中间层的存在,就可以在操作真实节点之前进行对应的处理,处理的结果反映到真实节点上,这个真实节点可以是浏览器环境,也可以是Native环境

virtual Dom真的快吗?其实virtual Dom只是在更新的时候快,在应用初始的时候不一定快

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const div = document.createElement('div');
let str = ''
for(let k in div){
  str+=','+k
}
console.log(str)
jsx&createElement

jsx可以声明式的描述视图,提升开发效率,通过babel可以转换成React.createElement()的语法糖,也是js语法的扩展。

jsx是ClassComponent的render函数或者FunctionComponent的返回值,可以用来表示组件的内容,在经过babel编译之后,最后会被编译成React.createElement,这就是为什么jsx文件要声明import React from 'react'的原因(react17之后不用导入),你可以在 <a name="https://www.babeljs.cn/repl">babel编译jsx</a> 站点查看jsx被编译后的结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
`React.createElement`的源码中做了如下几件事
  • 处理config,把除了保留属性外的其他config赋值给props
  • 把children处理后赋值给props.children
  • 处理defaultProps
  • 调用ReactElement返回一个jsx对象(virtual-dom)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ReactElement.js
export function createElement(type, config, children) {
  let propName;

  const props = {};

  let key = null;
  let ref = null;
  let self = null;
  let source = null;

  if (config != null) {
    //处理config,把除了保留属性外的其他config赋值给props
    //...
  }

  const childrenLength = arguments.length - 2;
  //把children处理后赋值给props.children
  //...

  //处理defaultProps
  //...

  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}

const ReactElement = function(type, key, ref, self, source, owner, props) {
  const element = {
    $$typeof: REACT_ELEMENT_TYPE,//表示是ReactElement类型

    type: type,//class或function
    key: key,//key
    ref: ref,//ref属性
    props: props,//props
    _owner: owner,
  };

  return element;
};

这里的typeof表示的是组件的类型,例如在源码中有一个检查是否是合法Element的函数,就是根object.$$typeof === REACT_ELEMENT_TYPE来判断的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ReactElement.js
export function isValidElement(object) {
  return (
    typeof object === 'object' &&
    object !== null &&
    object.$$typeof === REACT_ELEMENT_TYPE
  );
}

如果组件是ClassComponent则type是class本身,如果组件是FunctionComponent创建的,则type是这个function,源码中用ClassComponent.prototype.isReactComponent来区别二者。注意class或者function创建的组件一定要首字母大写,不然后被当成普通节点,type就是字符串。

jsx对象上没有优先级、状态、effectTag等标记,这些标记在Fiber对象上,在mount时Fiber根据jsx对象来构建,在update时根据最新状态的jsx和current Fiber对比,形成新的workInProgress Fiber,最后workInProgress Fiber切换成current Fiber。

render
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ReactDOMLegacy.js
export function render(
  element: React$Element<any>,//jsx对象
  container: Container,//挂载dom
  callback: ?Function,//回调
) {
  
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}

可以看到render所做的事也就是调用legacyRenderSubtreeIntoContainer,这个函数在下一章讲解,这里重点关注ReactDom.render()使用时候的三个参数。

component
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ReactBaseClasses.js
function Component(props, context, updater) {
  this.props = props;//props属性
  this.context = context;//当前的context
  this.refs = emptyObject;//ref挂载的对象
  this.updater = updater || ReactNoopUpdateQueue;//更新的对像
}

Component.prototype.isReactComponent = {};//表示是classComponent

component函数中主要在当前实例上挂载了props、context、refs、updater等,所以在组件的实例上能拿到这些,而更新主要的承载结构就是updater, 主要关注isReactComponent,它用来表示这个组件是类组件

总结:jsx是React.createElement的语法糖,jsx通过babel转化成React.createElement函数,React.createElement执行之后返回jsx对象,也叫virtual-dom,Fiber会根据jsx对象和current Fiber进行对比形成workInProgress Fiber

pureComponent也很简单,和component差不多,他会进行原型继承,然后赋值isPureReactComponent

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function PureComponent(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}

const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
pureComponentPrototype.constructor = PureComponent;
Object.assign(pureComponentPrototype, Component.prototype);
pureComponentPrototype.isPureReactComponent = true;

export {Component, PureComponent};

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
react源码解析5.jsx&核心api
一句话概括就是,用js对象表示dom信息和结构,更新时重新渲染更新后的对象对应的dom,这个对象就是React.createElement()的返回结果
全栈潇晨
2021/06/04
4840
react源码解析5.jsx&核心api
【React源码解读】- 组件的实现
react使用也有一段时间了,大家对这个框架褒奖有加,但是它究竟好在哪里呢? 让我们结合它的源码,探究一二!(当前源码为react16,读者要对react有一定的了解)
用户2356368
2024/02/04
1220
【React源码解读】- 组件的实现
【React源码解读】- 组件的实现
react使用也有一段时间了,大家对这个框架褒奖有加,但是它究竟好在哪里呢? 让我们结合它的源码,探究一二!(当前源码为react16,读者要对react有一定的了解)
用户2356368
2019/04/03
7050
【React源码解读】- 组件的实现
React中的JSX原理渐析
在react官方中讲到,关于jsx语法最终会被babel编译成为React.createElement()方法。
19组清风
2021/11/15
2.4K0
React中的JSX原理渐析
react源码解析--jsx&核心api
一句话概括就是,用js对象表示dom信息和结构,更新时重新渲染更新后的对象对应的dom,这个对象就是React.createElement()的返回结果
长腿程序员165858
2022/12/12
3670
react源码解析5.jsx&核心api
一句话概括就是,用js对象表示dom信息和结构,更新时重新渲染更新后的对象对应的dom,这个对象就是React.createElement()的返回结果
zz1998
2021/11/30
4200
react源码分析:babel如何解析jsx_2023-02-27
同作为MVVM框架,React相比于Vue来讲,上手更需要JavaScript功底深厚一些,本系列将阅读React相关源码,从jsx -> VDom -> RDOM等一些列的过程,将会在本系列中一一讲解
flyzz177
2023/02/27
2770
React源码分析1-jsx转换及React.createElement
我们从 react 应用的入口开始对源码进行分析,创建一个简单的 hello, world 应用:
goClient1992
2022/10/06
9430
React源码解读【一】API复习与基础
四年,如人生小溪中的一洼清水,如历史长河中的一点水滴,而却就是这四年,我完成了从懵懂到成熟的蜕变。回首这四年,有过创业,有过生病,有过说不出的苦楚,也有过让我笑不间断的喜悦。
合一大师
2020/07/20
6980
React源码解读【一】API复习与基础
React源码解析之React.createRef()/forwardRef()
一、React.createRef() GitHub: https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react/src/ReactCreateRef.js
进击的小进进
2019/09/05
1.6K0
React源码解析之React.createRef()/forwardRef()
react源码分析:babel如何解析jsx
同作为MVVM框架,React相比于Vue来讲,上手更需要JavaScript功底深厚一些,本系列将阅读React相关源码,从jsx -> VDom -> RDOM等一些列的过程,将会在本系列中一一讲解
flyzz177
2022/10/19
3580
React源码学习入门(二)React的render究竟返回的是什么?
可以很明显的看出来,render返回值是一个ReactNode,而ReactNode可以是很多类型,其中最重要常见的类型是ReactElement。
孟健
2022/09/21
7200
React 源码深度解读(一):首次DOM元素渲染 - Part 1
React 是一个十分庞大的库,由于要同时考虑 ReactDom 和 ReactNative ,还有服务器渲染等,导致其代码抽象化程度很高,嵌套层级非常深。阅读 React 源码是一个非常艰辛的过程,在学习过程中给我帮助最大的就是这个系列文章。作者对代码的调用关系梳理得非常清楚,而且还有配图帮助理解,非常值得一读。站在巨人的肩膀之上,我尝试再加入自己的理解,希望对有志于学习 React 源码的读者带来一点启发。
Dickensl
2022/06/14
6280
React 源码深度解读(一):首次DOM元素渲染 - Part 1
2.react心智模型(来来来,让大脑有react思维吧)
​ 视频课程的目的是为了快速掌握react源码运行的过程和react中的scheduler、reconciler、renderer、fiber等,并且详细debug源码和分析,过程更清晰。
zz1998
2021/12/09
7570
React.forwardRef的应用场景及源码解析
ref 的作用是获取实例,可能是 DOM 实例,也可能是 ClassComponent 的实例。
进击的小进进
2020/02/24
2.2K0
React.forwardRef的应用场景及源码解析
React 源码:ReactElement 和 FiberNode 是什么?
大家好,我是前端西瓜哥。今天学习一下 ReactElement 和 FiberNode。
前端西瓜哥
2022/12/21
9410
React 源码:ReactElement 和 FiberNode 是什么?
react的jsx和React.createElement是什么关系?面试常问
在React17之前,我们写React代码的时候都会去引入React,并且自己的代码中没有用到,这是为什么呢?
beifeng1996
2022/10/03
5430
React核心工作原理
react中虚拟dom+jsx的设计一开始就有,vue则是演进过程中才出现的,2.0版本后出现。
xiaofeng123aa
2022/09/28
9630
React源码解析之React.createElement()和ReactElement()
一、JSX语法转换到Js语法 从 JSX 转换到 JS 会用到React.createElement(),所以先熟悉下 JSX 到 JS 的转换。
进击的小进进
2019/09/05
1.3K0
React源码解析之React.createElement()和ReactElement()
React 进阶 - JSX
最后,在调和阶段,上述 React element 对象的每一个子节点都会形成一个对应的 fiber 对象,然后通过 sibling、return、child 将每一个 fiber 对象联系起来。
Cellinlab
2023/05/17
7900
React 进阶 - JSX
相关推荐
react源码解析5.jsx&核心api
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验