Skip to content

Latest commit

 

History

History
79 lines (59 loc) · 3.97 KB

File metadata and controls

79 lines (59 loc) · 3.97 KB

全栈潇晨 人人都能读懂的react源码解析

课程地址 https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b334cf10a4003b63471d

virtual Dom

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

为什么要用virtual Dom

  • 大量的dom操作慢,很小的更新都有可能引起页面的重新排列,js对象由于在内存中,处理起来更快,可以通过diff算法比较新老virtual Dom的差异,并且批量、异步、最小化的执行dom的变更,以提高性能
  • 另外就是可以跨平台jsx --> ReactElement对象 --> 真实节点有中间层的存在,就可以在操作真实节点之前进行对应的处理,处理的结果反映到真实节点上,这个真实节点可以是浏览器环境,也可以是Native环境

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

jsx&createElement

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

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

React.createElement的源码中做了如下几件事

  • 处理config,把除了保留属性外的其他config赋值给props
  • 把children处理后赋值给props.children
  • 处理defaultProps
  • 调用ReactElement返回一个jsx对象(virtual-dom)
   const element = {
    $$typeof: REACT_ELEMENT_TYPE, // 表示ReactElement类型 例如在源码中有一个检查是否是合法Element的函数,就是根object.$$typeof === REACT_ELEMENT_TYPE来判断的

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

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

component

//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,它用来表示这个组件是类组件

pureComponent也很简单,和component差不多,他会进行原型继承,然后赋值isPureReactComponent 可以用Memo实现一个纯组件

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};