美文网首页Web前端之路
React基础渲染机制

React基础渲染机制

作者: 皮神雷卡丘 | 来源:发表于2019-09-29 15:04 被阅读0次

ReactDOM.js

var ReactDOM = {
  findDOMNode: findDOMNode,
  render: ReactMount.render,
  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
  version: ReactVersion,

  /* eslint-disable camelcase */
  unstable_batchedUpdates: ReactUpdates.batchedUpdates,
  unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer
  /* eslint-enable camelcase */
};

ReactDOM.render()

ReactDOM.render()方法来自ReactMount文件的render方法:

render: function (nextElement, container, callback) {
    return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback);
  },

Render()将子树nextElement注入到指定的container中,并调用其回调方法_renderSubtreeIntoContainer,它将完成
(1)React.createElement 生成待插入节点的虚拟DOM实例对象
(2)对新旧虚拟DOM进行对比,找到需要更新的地方批量改动。初次渲染直接将虚拟DOM转换为真实DOM
(3)将DOM插入到container中

Diff 算法

简单mark一下(详细了解需要去看专门的文档):
1.不同的节点类型 直接删去旧的节点,新建一个新的节点。
2.相同节点类型 如果没有key对比它们的属性,只改变需要改变的属性,如果配置了key将作为唯一的节点不是改变其属性,而是直接操作此节点。

_renderSubtreeIntoContainer

_renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
  /*
  *将callback放入到React的更新队列中,判断nextElement有效性以及当前是发开环境还是生产环境。(代码省略)
  */
  …
  var nextWrappedElement = React.createElement(TopLevelWrapper, { child: nextElement });
  // 返回一个ReactElement实例对象,也就是虚拟DOM的实例对象,下面就要把它渲染出来
  var nextContext;
  /*(1)判断是否有parentComponent,如果有则将其写到parentComponent*/
  if (parentComponent) {
    var parentInst = ReactInstanceMap.get(parentComponent);
    nextContext = parentInst._processChildContext(parentInst._context);
  } else {
    nextContext = emptyObject;
  }
  var prevComponent = getTopLevelWrapperInContainer(container);
  /*
 *(2)判断是否有prevComponent,如果有则取其child,利用Diff算法判断是否需要更新,如果需要则调用_updateRootComponen 方法,并return结果。对于初次渲染不需要该过程。 
 */
  if (prevComponent) {
    var prevWrappedElement = prevComponent._currentElement;
    var prevElement = prevWrappedElement.props.child;
    // shouldUpdateReactComponent方法判断是否需要更新,对同一DOM进行比较,type相同,key(如果有)相同的组件做DOM diff 
    if (shouldUpdateReactComponent(prevElement, nextElement)) {
      var publicInst = prevComponent._renderedComponent.getPublicInstance();
      var updatedCallback = callback && function () {
        callback.call(publicInst);
      };
      ReactMount._updateRootComponent(prevComponent, nextWrappedElement, nextContext, container, updatedCallback);
      return publicInst;
    } else {
      ReactMount.unmountComponentAtNode(container);
    }
  }
  /*
  *(3)对于prevElement为null直接跳到此步
  var reactRootElement = getReactRootElementInContainer(container);
  var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement);
  var containerHasNonRootReactChild = hasNonRootReactChild(container);
  var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild;
  /*
  *3核心部分,调用_renderNewRootComponent,_renderedComponent,getPublicInstance三个方法,
  */
  var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, nextContext)._renderedComponent.getPublicInstance();
  if (callback) {
    callback.call(component);
  }
  return component;
}

相关文章

  • React基础渲染机制

    ReactDOM.js ReactDOM.render() ReactDOM.render()方法来自ReactM...

  • React 渲染机制

    React 渲染过程 在使用 React 构建应用时,总有一个步骤是将组件 / 虚拟 DOM 树渲染到真实的 DO...

  • 前端

    React基础[https://www.jianshu.com/p/c6901ceb9193]React首次渲染[...

  • React学习---渲染机制

    在介绍React渲染机制之间先来说一说下面几个概念,对于新入手React的学员来说,经常会被搞蒙圈。 Rea...

  • 从中断机制看 React Fiber 技术

    前言 React 16 开始,采用了 Fiber 机制替代了原有的同步渲染 VDOM 的方案,提高了页面渲染性能和...

  • 前端基础知识总结-1

    #前端基础 # ## JavaScript基础 ## ###渲染机制与变量 ### script代码为什么放到bo...

  • React基础-元素渲染

    当React元素被创建之后,是无法改变其内容或属性的。 一个元素就好像是动画里的一帧,它代表应用界面在某一时间点的...

  • React手记

    React手记 1、 2、React元素渲染 React元素渲染是通过方法ReactDOM.render(elem...

  • 第七节:React列表渲染与数据收集

    1. 列表渲染 1.1 列表渲染说明: 列表渲染 先将列表数据转为React元素列表, 然后在渲染 React会将...

  • 第七节:React列表渲染与数据收集

    1. 列表渲染 1.1 列表渲染说明: 列表渲染 先将列表数据转为React元素列表, 然后在渲染 React会将...

网友评论

    本文标题:React基础渲染机制

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