preact源码分析:createElement

重要方法,将 jsx 转化为 vdom
更新于: 2021-12-19 12:57:29
 create-elemetn.js 主体结构

方法的作用

Create an virtual node (used for JSX)

createElement入参

  • type: String | Function
  • props: any
  • children: []/string/null 等

可能的参数形式

  • createElement('div', { id:'hello'});
  • createElement('div', { id:'hello'}, ‘Hello world’);
  • createElement('div', { id:'hello'}, [ ‘child1’, ‘child2']);
  • createElement('div', { id:'hello'}, child1, child2);
  • ….

createElement

  1. ref/key 以及其它 参数
  2. children 考虑,可能以多作3个方式传入
  3. 处理 defaultProps,默认属性
  4. 交给 createNode 方法进行处理 (type, normalizedProps, key, ref, null)

伪代码实现为:

export function createElement(type, props, children) {
  // 1. 取出 ref/key 和其它标准化参数
  let { ref, key, ...normalizedProps } = props;

  // 2. 拿到 children
  if (arguments.length > 2) {
    normalizedProps.children =
      arguments.length > 3 ? slice.call(arguments, 2) : children;
  }

  // If a Component VNode, check for and apply defaultProps
  // Note: type may be undefined in development, must never error here.
  // 3. funcl.defaultProps 的处理
  if (typeof type == "function" && type.defaultProps != null) {
    for (i in type.defaultProps) {
      if (normalizedProps[i] === undefined) {
        normalizedProps[i] = type.defaultProps[i];
      }
    }
  }

  // 4. 创建 vnode
  return createVNode(type, normalizedProps, key, ref, null);
}

个人看法

这个拿 children,没有支持大于3个参数的必要,除非兼容 React

// 2. 拿到 children
if (arguments.length > 2) {
  normalizedProps.children =
    arguments.length > 3 ? slice.call(arguments, 2) : children;
}