手写React一render

const Didact = {
  createElement,
  render,
};

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

function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map((child) =>
        typeof child === "object" ? child : createTextElement(child)
      ),
    },
  };
}

/** @jsx Didact.createElement */
const element = (
  
bar
); // const element = Didact.createElement( // "div", // { id: "foo" }, // Didact.createElement("a", null, "bar"), // Didact.createElement("b") // ); function render(element, container) { const dom = element.type == "TEXT_ELEMENT" ? document.createTextNode("") : document.createElement(element.type); const isProperty = (key) => key !== "children"; Object.keys(element.props) .filter(isProperty) .forEach((name) => { dom[name] = element.props[name]; }); element.props.children.forEach((child) => render(child, dom)); container.appendChild(dom); } const container = document.getElementById("root"); Didact.render(element, container);

/** @jsx Didact.createElement */

是告诉babel jsx在转换的时候使用我们自己的方法Didact.createElement。

Didact.render(element, container);

element是jsx转换过后的数据结构,再根据我们自己的数据结构渲染element。

render过程如下

 1 创建dom

const dom =
    element.type == "TEXT_ELEMENT"
      ? document.createTextNode("")
      : document.createElement(element.type);

 2 把除去children属性的其他属性赋值到真实dom上面

  const isProperty = (key) => key !== "children";
  Object.keys(element.props)
    .filter(isProperty)
    .forEach((name) => {
      dom[name] = element.props[name];
    });

3 如果dom还有子节点,那么通过render递归把子节点添加到父节点上面

element.props.children.forEach((child) => render(child, dom));

4  把子节点dom添加到父节点dom上

container.appendChild(dom);

你可能感兴趣的:(React,react.js,javascript,前端)