React底层源码分析之------createElement

export function createElement(type, config, children) {
  //propName 变量用于储存后面需要用到的元素属性
  let propName;

  // props 变量用于储存元素属性的键值对集合
  const props = {};

  //key、ref、self、source均为react元素的属性
  let key = null;
  let ref = null;
  let self = null;
  let source = null;

  //config对象中存储的元素的属性
  if (config != null) {
    //进来之后的第一件事: 依次对ref、key、self和source属性赋值
    if (hasValidRef(config)) {
      ref = config.ref;

      if (__DEV__) {
        warnIfStringRefCannotBeAutoConverted(config);
      }
    }

    //此处将key值字符串化
    if (hasValidKey(config)) {
      //开发环境下的配置
      if (__DEV__) {
        checkKeyStringCoercion(config.key);
      }
      key = '' + config.key;
    }

    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;
    // 把config里面的属性一个一个挪到之前声明的props对象里面
    for (propName in config) {
      if (
        hasOwnProperty.call(config, propName) &&
        !RESERVED_PROPS.hasOwnProperty(propName)
      ) {
        props[propName] = config[propName];
      }
    }
  }

  //childrenLength指的是当前元素的子元素的个数,减去2是type和config两个参数占用的长度
  const childrenLength = arguments.length - 2;
  //如果除去type和config,就是剩一个参数,一般意味着文本节点出现了
  if (childrenLength === 1) {
    //直接把这个参数的值赋给props.children
    props.children = children;
    //处理嵌套多个子元素的情况
  } else if (childrenLength > 1) {
    //声明一个子元素数组
    const childArray = Array(childrenLength);
    //把子元素从arguments除去type和config推进childArray数组里
    for (let i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    if (__DEV__) {
      if (Object.freeze) {
        Object.freeze(childArray);
      }
    }
    //最后把数组赋值给props.children
    props.children = childArray;
  }

  // 处理defaultProps
  if (type && type.defaultProps) {
    const defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }
  //开发环境下的配置
  if (__DEV__) {
    if (key || ref) {
      const displayName =
        typeof type === 'function'
          ? type.displayName || type.name || 'Unknown'
          : type;
      if (key) {
        defineKeyPropWarningGetter(props, displayName);
      }
      if (ref) {
        defineRefPropWarningGetter(props, displayName);
      }
    }
  }
  //返回一个调用ReactElement执行方法,并传入刚才处理过的参数
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值