-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
preact 源码学习系列之一:JSX解析与DOM渲染 #103
Comments
React的代码结构看得我蛋疼。。。完全找不着北😂。 |
@javoski 我也是,满眼都是什么 React、Component 这些单词,看得眼都花了。 |
是不是应该把 |
@deot 引入概念 |
@youngwind 使用 |
imho, |
@shadeofgod 不是这样的,如果你一次性插入 |
@deot 没太明白你的意思。。。 |
@shadeofgod 好像又讨论了其他问题,我是指原生操作;
我的理解是:数据驱动,虚拟DOM更趋向的是提升了开发效率,减少开发者各种不必要的DOM操作达到性能提升 |
提升开发效率是因为框架帮我们完成了数据和视图之间的绑定,使得开发者只需要关注数据的变化,而数据到视图的映射利用了Virtual DOM这一思路来提升性能。 |
deot的观点很好。shadeofgod姿态很高,其实没有听出关键点,在自说自话。前天我就用ng1比较vue,循环1000次的变化,ng1完爆vue,估计很多网上的观点都是有前提的。并不是说真的就能搬过来的。 |
@william-xue 我有什么说错说漏的地方欢迎直接指出来,本来就是抱着学习交流的心态来的,单纯的文字很多时候都不能表达完整的感情色彩,技术上的事情我倾向于有问题放开了说清楚,没必要在别人的博文下说我姿态高把我批判一番。 |
@EzioKissshot 这里的代码是 bable5 编译之后的, |
@youngwind 谢谢! |
setAttributes(node, key, attrs[key]); 是不是引用了lodash之类的库? |
@william-xue 不是,此处代码没贴完整,setAttributes 是我自己定义的函数,详情看这里:https://github.com/youngwind/fake-preact/blob/master/preact.js#L189-L202 |
前言
一直以来我都想研究 React 的源码,但总是看不懂。即便是去翻看最早的源码,代码量也有1万多行,研究起来难度太高了,这个问题困扰了我很久。
直到前两天我跟同事讨论起这个问题,忽然发现一个可行的方法:React 的源码太难懂,可以看 preact 的源码啊!为什么呢?因为 React 代表的是一种思想,能实现这种思想的不只有 React。preact 便是一个 mini 版的 React,其代码量很少,目前也就 1000多行,但是已经实现了 React 的主要功能。
这的确是一个很不错的研究方法,值得推荐。那么,我们便按着这种思路来研究,此次参考的是 preact 2.0.1 版本。
目标
React 类框架功能很多,应该从哪个角度入手的。
答案:从“解析 JSX,渲染 DOM 入手”
举个例子:
问题是:给定一段 JSX 和一个挂载点,如何解析 JSX,生成真实 DOM 并挂载到页面中呢?
谁来解析 JSX
要想生成真实 DOM,必须有一个层级嵌套的对象,此对象表征了 DOM 的嵌套结构。我们只需要遍历此对象,便可拼接出 DOM。
问题是: 如何把这段 JSX 格式的字符串转化为对应嵌套结构的对象呢? 这本质上是 HTML 解析器所要完成的事情。然而,我无力实现一个 HTML 解析器,怎么办呢? → 答案是使用 babel。
babel 作为一个代码转换工具,它不仅仅能将 ES6 转化成 ES5,也能够将 JSX 转换成某个函数嵌套调用的结构,而这个函数是可以自定义的,具体请参考 transform-react-jsx
请注意一下两点:
ok,经过 babel 转换之后,原有的 JSX 变成了下面这个样子。
从图中我们可以看到:经过 babel 转换之后,JSX 变成了 preact.h 的嵌套调用。
因此,问题就转化为:如何编写这样的一个 h 函数,使得上述嵌套调用最终返回一个层级嵌套的对象,此对象表征了 DOM 的结构。
h 函数的编写
h 是这样的一个函数,接收参数为:标签名、属性值和子元素,返回一个对象,该对象描述了一个 DOM 节点。
经过这样的 h 函数的嵌套调用,最终返回的结果如下:
DOM 渲染
有了上面的 vNode 结构,我们便能将之转换成真实的 DOM 元素。此处逻辑并不复杂,无非是递归的调用,代码如下:
最终实现效果如下图所示:
后话
本文实现的具体代码参考这里,这只是一个最基本的 demo,后续还有很多有待探索的功能,比如构造 Component 类,比如 DOM 的 diff 和 update 等等。
参考资料:WTF is JSX, By developit
--------------- EOF ----------------
The text was updated successfully, but these errors were encountered: