美文网首页React & React Native
react源代码学习笔记

react源代码学习笔记

作者: lazahata | 来源:发表于2019-02-15 19:51 被阅读0次

本文开始于2019年2月15日,还在不断更新中。。
希望通过摘录和解释react最关键的代码,帮助我自己和其他人理解react源码
你不可能只阅读文章就理解react,你必须阅读react源码才能理解react :)
这里可能有很多错误和漏洞,欢迎在评论区指正,一切以源码为准。

react最关键的代码

操作dom

浏览器在内存里存了一堆数据,是一个树,叫做dom,修改dom里的数据会触发浏览器重绘界面,如果频繁的触发浏览器重绘,效率比较低。

react在内存里存了类似的一堆数据,也是一个树,叫做virtual dom,react应用在收到事件(点击,网络。。。)后先修改virtual dom, 修改virtual dom只修改virtual dom树里的数据,不会触发重绘。

react 隔一段时间找出virtual dom和dom的区别,批量的把这些区别应用到dom上,以此提升性能。

但归根结底,要修改dom,才能让浏览器重绘,才能让用户看到界面改变,操作dom的代码在这两个文件:
packages/react-dom/src/client/ReactDOMComponent.js
packages/react-dom/src/client/ReactDOMHostConfig.js
从下面的函数实现里可以找到react最终调用dom的api的地方,为方便阅读,代码有删改,此处只略举几例,完整的代码请阅读react-dom源码

// 以下代码在ReactDOMComponent.js

// 获取dom对象
function getOwnerDocumentFromRootContainer(
  rootContainerElement: Element | Document,
): Document {
  return rootContainerElement.nodeType === DOCUMENT_NODE
    ? (rootContainerElement: any)
    : rootContainerElement.ownerDocument;
}

//  新建Element
export function createElement(
  type: string,
  props: Object,
  rootContainerElement: Element | Document,
  parentNamespace: string,
): Element {
...
if (type === 'script') {
     const div = ownerDocument.createElement('div');
      div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
      const firstChild = ((div.firstChild: any): HTMLScriptElement);
      domElement = div.removeChild(firstChild);
    } else if (typeof props.is === 'string') {
     domElement = ownerDocument.createElement(type, {is: props.is});
    } else {
      domElement = ownerDocument.createElement(type);
   if (type === 'select' && props.multiple) {
        const node = ((domElement: any): HTMLSelectElement);
       } }
  } else {
    domElement = ownerDocument.createElementNS(namespaceURI, type);
  }
...
}

// 新建TextNode
export function createTextNode(
  text: string,
  rootContainerElement: Element | Document,
): Text {
  return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(
    text,
  );
}

// 以下代码在ReactDOMHostConfig.js
// append 子元素
export function appendChild(
  parentInstance: Instance,
  child: Instance | TextInstance,
): void {
  parentInstance.appendChild(child);
}

相关文章

网友评论

    本文标题:react源代码学习笔记

    本文链接:https://www.haomeiwen.com/subject/gvepeqtx.html