React原理(一):动手实现React.createElement和ReactDOM.render

首先我们来看一个最简单的hello world例子

function App() {
  return (
      <p className="title">hello world</p>
  );
}

ReactDOM.render(<APP />, document.getElementById("root"));

在babel中转化为如下代码

function App() {
  return React.createElement(
    "p",
    { className: "title" },
    "hello world"
  );
}

ReactDOM.render(React.createElement(APP, null), document.getElementById("root"));

打印App(),返回的对象就是一个虚拟DOM

屏幕快照 2018-11-28 00.34.27.png

实现React.createElement

通过上文,我们可以知道jsx本质是个语法糖。jsx片段会被转译成用React.createElement方法包裹的代码。所以第一步,我们来实现这个React.createElement方法

function createElement(tag, attrs, ...children){
    return {
        tag,
        attrs,
        children
    }
}

第一个参数是DOM节点的标签名

第二个参数是一个对象,里面保存了所有的属性

从第三个参数开始,就是它的子节点。

我们的createElement方法返回的对象记录了这个DOM节点所有的信息,换言之,通过它我们就可以生成真正的DOM,这个记录信息的对象我们称之为虚拟DOM

实现ReactDOM.render

我们来看这段代码

ReactDOM.render(
  React.createElement("p", { className: "title" }, "hello world"),
  document.getElementById("root")
)

所以render的第一个参数实际上接受的是createElement返回的对象,也就是虚拟DOM
而第二个参数则是挂载的目标DOM

我们来实现这个render方法

  function render(vnode, container) {
    //当vnode为字符串时,渲染结果是一段文本
    if (typeof vnode === "string") {
      const textNode = document.createTextNode(vnode)
      return container.appendChild(textNode)
    }

    const dom = document.createElement(vnode.tag)

    //设置属性
    if (vnode.attrs) {
      Object.keys(vnode.attrs).forEach(key => {
        const value = vnode.attrs[key]
        dom.setAttribute(key, value)
      })
    }

    //递归渲染子节点
    vnode.children.forEach(child=> render(child, dom))

    return container.appendChild(dom)
  }

参考资料

从零开始实现一个React(一):JSX和虚拟DOM

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,867评论 1 18
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 1,087评论 0 1
  • 以下内容是我在学习和研究React时,对React的特性、重点和注意事项的提取、精练和总结,可以做为React特性...
    科研者阅读 8,308评论 2 21
  • HTML模版 之后出现的React代码嵌套入模版中。 1. Hello world 这段代码将一个一级标题插入到指...
    ryanho84阅读 6,334评论 0 9
  • 心累
    水为之而寒于水阅读 69评论 0 0