美文网首页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