React源码解析(一)

React源码解析(一)

github地址

要点掌握:三个API作用,Component、render、createElement

jsx模板渲染的过程:

image.png

createElement

function createElement(type, props, ...children) {
  if (props) {
    delete props.__source;
    delete props.__self;
  }

  return {
    type: type,
    props: {
      ...props,
      // 为了保持返回的树状结构一致,这里对文本型children做了包装
      children: children.map(child =>
        typeof child === "object" ? child : createTextNode(child)
      )
    }
  };
}

function createTextNode(text) {
  return {
    type: "TEXT",
    props: {
      children: [],
      nodeValue: text
    }
  };
}

render

function render(vnode, container) {
  // vnode->node
  const node = createNode(vnode);
  // 把node更新到container
  container.appendChild(node);
}

// 根据vnode,创建一个node
function createNode(vnode) {
  const {type, props} = vnode;
  let node;
  if (typeof type === "function") {
    node = type.isReactComponent
      ? // node = type.prototype.isReactComponent
        updateClassComponent(vnode)
      : updateFunctionComponent(vnode);
  } else if (type === "TEXT") {
    node = document.createTextNode("");
  } else if (type) {
    node = document.createElement(type);
  } else {
    node = document.createDocumentFragment();
  }
  updateNode(node, props);
  reconcilerChildren(props.children, node);
  return node;
}

function reconcilerChildren(children, node) {
  for (let i = 0; i < children.length; i++) {
    let child = children[i];
    // 遍历 创建元素
    // 判读children[i]类型
    if (Array.isArray(child)) {
      for (let j = 0; j < child.length; j++) {
        render(child[j], node);
      }
    } else {
      render(children[i], node);
    }
  }
}

// 更新节点上属性,如className、nodeValue等
function updateNode(node, nextVal) {
  Object.keys(nextVal)
    .filter(k => k !== "children")
    .forEach(k => {
      if (k.slice(0, 2) === "on") {
        // 以on开头,就认为是一个事件,源码处理复杂一些,
        let eventName = k.slice(2).toLocaleLowerCase();
        node.addEventListener(eventName, nextVal[k]);
      } else {
        node[k] = nextVal[k];
      }
    });
}

// function组件,返回node
function updateFunctionComponent(vnode) {
  const {type, props} = vnode;
  const vvnode = type(props);
  const node = createNode(vvnode);
  return node;
}

function updateClassComponent(vnode) {
  const {type, props} = vnode;
  const cmp = new type(props); //实例化
  const vvnode = cmp.render();
  const node = createNode(vvnode);
  return node;
}
export default {
  render
};

component

export default class Component {
  static isReactComponent = {};
  constructor(props) {
    this.props = props;
  }
}
发布了171 篇原创文章 · 获赞 246 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/weixin_42042680/article/details/104743616