react理解(1)

129 阅读1分钟

jsx

jsx是声明式的描述试图,也是js的扩展,通过babel转换成React.createElement的语法糖

babel编译jsx

image.png

通过以上编译:class或者function创建的组件一定要首字母大写,不然后被当成普通节点,type就是字符串

React.createElement:

function createElement(type, config, children) {

  var propName; // Reserved names are extracted

  var props = {};
  var key = null;
  var ref = null;
  var self = null;
  var source = null;

  // 获取 key,ref,把除了保留的字段之外的config赋予给props
  if (config != null) {
    if (hasValidRef(config)) {
      ref = config.ref;

      {
        warnIfStringRefCannotBeAutoConverted(config);
      }
    }

    if (hasValidKey(config)) {
      {
        checkKeyStringCoercion(config.key);
      }

      key = '' + config.key;
    }

    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source; // Remaining properties are added to a new props object

    for (propName in config) {
      if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
        props[propName] = config[propName];
      }
    }
  } // Children can be more than one argument, and those are transferred onto
  // the newly allocated props object.


  // arguments.length - 2 是去掉type和config, 保留 childrens
  var childrenLength = arguments.length - 2;

  // childrenLength 为1,代表只有一个children
  // 大于1,生成一个childArray,赋值给child
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    var childArray = Array(childrenLength);

    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }

    {
      if (Object.freeze) {
        Object.freeze(childArray);
      }
    }

    props.children = childArray;
  } // Resolve default props



  // 默认的defaultProps的值 赋值给props
  if (type && type.defaultProps) {
    var defaultProps = type.defaultProps;

    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }

  
  // 返回一个vim Dom,  element对象
  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
}

ReactElement:

// $$typeof 是一个标识,REACT_ELEMENT_TYPE:表示是一个react.element 类型
var ReactElement = function (type, key, ref, self, source, owner, props) {
  var element = {
    // This tag allows us to uniquely identify this as a React Element
    $$typeof: REACT_ELEMENT_TYPE,
    // Built-in properties that belong on the element
    type: type,
    key: key,
    ref: ref,
    props: props,
    // Record the component responsible for creating this element.
    _owner: owner
  };

  return element;
};

virtual Dom

virtual Dom是什么

用js的对象保存dom和结构,以对象的形式保存在内存中,更新时,重新渲染更新后对应的dom,这个对象通过React.createElement返回

为什么要用virtual Dom

大量的dom操作会很慢,少量的dom操作也会使页面重新排列,而js对象存在内存中,处理起来更快,通过新老virtual dom的diff算法对比,可以批量,异步,最小化的执行dom的改动。
并且virtual dom可以跨平台, jsx ==> virtual dom ==> real dom(浏览器环境或者native环境)