编程开发 购物 网址 游戏 小说 歌词 地图 快照 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 开发 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
移动开发 架构设计 编程语言 互联网 开发经验 Web前端 开发总结
开发杂谈 系统运维 研发管理 数据库 云 计 算 Java开发
VC(MFC) Delphi VB C++(C语言) C++ Builder 其它开发语言 云计算 Java开发 .Net开发 IOS开发 Android开发 PHP语言 JavaScript
ASP语言 HTML(CSS) HTML5 Apache MSSQL数据库 Oracle数据库 PowerBuilder Informatica 其它数据库 硬件及嵌入式开发 Linux开发资料
  编程开发知识库 -> Java开发 -> ReactElement -> 正文阅读
 

[Java开发]ReactElement[第1页]

ReactElement模块用于创建ReactElement。
特别的,当用户自定义组件的render方法中调用React.createElement方法时,将向子组件元素注入容器组件的ReactCompositeComponent,意义时使当前子组件元素添加为容器组件元素的ref引用成为可能。

'use strict';

var _assign = require('object-assign');

// 保存容器组件,即用户自定义组件的ReactCompositeComponent实例,添加ref引用的需要
var ReactCurrentOwner = require('./ReactCurrentOwner');

// warning(condition,format) condition为否值,替换format中的"%s",并console.error警告
var warning = require('fbjs/lib/warning');

// 可否使用Object.defineProperty方法
var canDefineProperty = require('./canDefineProperty');

var hasOwnProperty = Object.prototype.hasOwnProperty;

// symbal或0xeac7标识ReactElementType
var REACT_ELEMENT_TYPE = require('./ReactElementSymbol');

var RESERVED_PROPS = {
  key: true,
  ref: true,
  __self: true,
  __source: true
};

var specialPropKeyWarningShown, specialPropRefWarningShown;

// 校验ref不是来自父组件的props.ref
function hasValidRef(config) {
  if (process.env.NODE_ENV !== 'production') {
    if (hasOwnProperty.call(config, 'ref')) {
      var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
      // 将父组件元素的props.ref添加为子组件元素的ref时,getter.isReactWarning为真
      if (getter && getter.isReactWarning) {
        return false;
      }
    }
  }
  return config.ref !== undefined;
}

// 校验key不是来自父组件的props.key
function hasValidKey(config) {
  if (process.env.NODE_ENV !== 'production') {
    if (hasOwnProperty.call(config, 'key')) {
      var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
      // 将父组件元素的props.key添加为子组件元素的key时,getter.isReactWarning为真
      if (getter && getter.isReactWarning) {
        return false;
      }
    }
  }
  return config.key !== undefined;
}

// 不允许设置props的key属性
function defineKeyPropWarningGetter(props, displayName) {
  var warnAboutAccessingKey = function () {
    if (!specialPropKeyWarningShown) {
      specialPropKeyWarningShown = true;
      process.env.NODE_ENV !== 'production' ? 
        warning(false, '%s: `key` is not a prop. Trying to access it will result ' 
          + 'in `undefined` being returned. If you need to access the same ' 
          + 'value within the child component, you should pass it as a different '
           + 'prop. (https://fb.me/react-special-props)', displayName) 
        : void 0;
    }
  };
  warnAboutAccessingKey.isReactWarning = true;
  Object.defineProperty(props, 'key', {
    get: warnAboutAccessingKey,
    configurable: true
  });
}

// 不允许设置props的ref属性
function defineRefPropWarningGetter(props, displayName) {
  var warnAboutAccessingRef = function () {
    if (!specialPropRefWarningShown) {
      specialPropRefWarningShown = true;
      process.env.NODE_ENV !== 'production' ? 
        warning(false, '%s: `ref` is not a prop. Trying to access it will result ' 
          + 'in `undefined` being returned. If you need to access the same ' 
          + 'value within the child component, you should pass it as a different ' 
          + 'prop. (https://fb.me/react-special-props)', displayName) 
        : void 0;
    }
  };
  warnAboutAccessingRef.isReactWarning = true;
  Object.defineProperty(props, 'ref', {
    get: warnAboutAccessingRef,
    configurable: true
  });
}

// 创建ReactElement,ReactElement.createElement用于转化处理配置项
// 参数type为用户自定义组件的构造函数,或者react封装的原生dom组件ReactDomElement的类型字符串,如"div"
// 参数key为ReactElement数组形式创建时添加的标识;同时,改变key值可用于销毁组件实例并重新生成实例
// 参数ref用于使当前ReactElement成为上层组件元素的ref引用
// 参数self、参数source调试时用,打印错误时区别于owner容器组件
// 参数owner顶级容器组件,在容器组件的render方法中调用React.createElement时注入
var ReactElement = function (type, key, ref, self, source, owner, props) {
  var element = {
    $$typeof: REACT_ELEMENT_TYPE,// symbal或0xeac7标识ReactElement

    type: type,
    key: key,
    ref: ref,
    props: props,

    // 顶层容器组件实例,为将当前组件元素即子组件元素设置为顶层容器组件的ref引用,'react-dom'下ReactRef模块中使用
    _owner: owner
  };

  if (process.env.NODE_ENV !== 'production') {
    // element._store.validated用于存储子节点的校验值
    element._store = {};

    if (canDefineProperty) {
      Object.defineProperty(element._store, 'validated', {
        configurable: false,
        enumerable: false,
        writable: true,
        value: false
      });
      Object.defineProperty(element, '_self', {
        configurable: false,
        enumerable: false,
        writable: false,
        value: self
      });
      Object.defineProperty(element, '_source', {
        configurable: false,
        enumerable: false,
        writable: false,
        value: source
      });
    } else {
      element._store.validated = false;
      element._self = self;
      element._source = source;
    }
    if (Object.freeze) {
      Object.freeze(element.props);
      Object.freeze(element);
    }
  }

  return element;
};

// 配置ReactElement元素的构造函数、props、props.children等属性,用于组件实例化时创建,以便组件实例化、挂载时进行渲染
// 参数type为用户自定义组件的构造函数,ReactComponent或ReactClass创建的组件,或普通函数返回ReactElement
//    或者字符串"div"等,表示react包装的原生dom组件ReactDomComponent
// 参数config包含子组件ref引用信息,及key标识数组中的某个ReactElement
//    以及__self属性,__source属性
//    以及组件元素props中的某些属性,即ref、key、__self、__source以外的属性
// 参数children添加为组件元素的props.children,组件实例化可按条件进行渲染
ReactElement.createElement = function (type, config, children) {
  var propName;

  var props = {};

  var key = null;
  var ref = null;
  var self = null;
  var source = null;

  if (config != null) {
    // 校验ref不是来自父组件的props.ref
    if (hasValidRef(config)) {
      ref = config.ref;
    }

    // 校验key不是来自父组件的props.key
    if (hasValidKey(config)) {
      key = '' + config.key;
    }

    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;

    // 将config中除ref、key、__self、__source以外的属性注入组件元素的props中
    for (propName in config) {
      if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
        props[propName] = config[propName];
      }
    }
  }

  // 从第三个参数起作为组件元素的props.children
  var childrenLength = arguments.length - 2;
  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 (process.env.NODE_ENV !== 'production') {
      if (Object.freeze) {
        Object.freeze(childArray);
      }
    }
    props.children = childArray;
  }

  // 将defaultProps注入props,前提是props中不存在值为真值的同名属性
  if (type && type.defaultProps) {
    var defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }

  // 不允许向props添加key、ref属性,props是ReactElement除外
  if (process.env.NODE_ENV !== 'production') {
    if (key || ref) {
      if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) {
        var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
        if (key) {
          defineKeyPropWarningGetter(props, displayName);
        }
        if (ref) {
          defineRefPropWarningGetter(props, displayName);
        }
      }
    }
  }

  // 创建ReactElement
  // ReactCurrentOwner.current为顶层容器组件实例,为将当前组件元素即子组件元素设置为顶层容器组件的ref引用,'react-dom'下ReactRef模块中使用
  // 即在用户自定义组件的render方法中调用React.createElement方法才使得ReactCurrentOwner.current为真值
  return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
};

// 创建组件元素的工厂函数,预先定义组件的构造函数type
ReactElement.createFactory = function (type) {
  var factory = ReactElement.createElement.bind(null, type);
  factory.type = type;
  return factory;
};

// 替换原组件元素的key
ReactElement.cloneAndReplaceKey = function (oldElement, newKey) {
  var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);

  return newElement;
};

// 以拷贝形式创建ReactElement
// 参数element待拷贝的ReactElement
// 参数config={ref,key,propName}重设新建组件元素的ref、key及部分props
// 参数children作为组件元素的props.children
ReactElement.cloneElement = function (element, config, children) {
  var propName;

  var props = _assign({}, element.props);

  var key = element.key;
  var ref = element.ref;
  var self = element._self;
  var source = element._source;
  var owner = element._owner;

  if (config != null) {
    // 重设ref,同时重设ref
    if (hasValidRef(config)) {
      ref = config.ref;
      owner = ReactCurrentOwner.current;
    }

    // 重设key
    if (hasValidKey(config)) {
      key = '' + config.key;
    }

    // 添加默认的defaultProps以及config中的props配置
    var defaultProps;
    if (element.type && element.type.defaultProps) {
      defaultProps = element.type.defaultProps;
    }
    for (propName in config) {
      if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
        if (config[propName] === undefined && defaultProps !== undefined) {
          props[propName] = defaultProps[propName];
        } else {
          props[propName] = config[propName];
        }
      }
    }
  }

  var childrenLength = arguments.length - 2;
  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];
    }
    props.children = childArray;
  }

  return ReactElement(element.type, key, ref, self, source, owner, props);
};

// 通过$$typeof标识判断是否ReactElement
ReactElement.isValidElement = function (object) {
  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
};

module.exports = ReactElement;

  Java开发 最新文章
nvm每次启动终端都要设置nvm use
单页面应用优缺点分析
微信小程序开发入门
jQueryEasyUi验证
CSS标签属性之position
ReactElement
Webpack+Babel+React的快速搭建
关于mongo 日期查询
Spring Boot基础教程8-web应用开发-模板引擎
java date time问题总结
上一篇文章      下一篇文章      查看所有文章
加:2017-02-15 22:11:03  更:2017-10-30 05:16:48 
VC(MFC) Delphi VB C++(C语言) C++ Builder 其它开发语言 云计算 Java开发 .Net开发 IOS开发 Android开发 PHP语言 JavaScript
ASP语言 HTML(CSS) HTML5 Apache MSSQL数据库 Oracle数据库 PowerBuilder Informatica 其它数据库 硬件及嵌入式开发 Linux开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年4日历
2018-4-23 1:53:40
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程开发知识库