Open youngwind opened 7 years ago
感谢博主分享的文章,真是简洁明了。我照着您的源码重新实现,在过程中遇到一个疑问,想请教博主一下:
在源码 91~96行, build
函数中
// 判断新子节点是否已经存在原有 DOM 中
newChildren.forEach((newChild, i) => {
if (children[i] !== newChild) {
out.appendChild(newChild);
}
});
这里为什么要使用appendChild
,不应该直接用 newChildren
替换掉 children
么。
在上一篇 #103 中,我们已经掌握了“如何解析渲染一段 JSX 结构”。今天,我们进一步研究:如何解析、渲染和更新组件。
变量的解析
在研究组件解析之前,我们先来看个更简单的例子。
问题:在渲染 Person 组件的时候,如何将 this.state.name 解析成真实值 "youngwind" 呢?是用正则匹配替换吗? 答案:不需要处理,因为 babel 已经帮我们处理好了。 请看编译后的代码。
this.state.name
被当做函数参数传递给 h 函数,因此 h 函数在执行的时候会对其进行自动求值。也就是说,对于变量的解析,我们并不需要做任何特殊处理。组件标签的解析
再看一个更复杂的例子。
编译后的代码如下:
组件的渲染与更新
有了上面的基础,我们来看看如何实现组件的渲染和更新,举个例子。
这段代码,我们期望的功能是:
具体的实现逻辑较为繁复,难以用文字描述清楚,我画了个流程图,可以对比着我实现的代码看。![preact组件渲染与更新逻辑图](https://cloud.githubusercontent.com/assets/8401872/26782156/b9f494a6-4a24-11e7-9130-7806d6d2e621.jpg)
效果
最终实现的效果如下所示。(注意,效果图中控制台会输出一些生命周期的信息,这部分的代码我在 demo 中省略了,完整的代码请参考这里。
)
后话
虽然在本文中已经实现了组件的更新,但是,并没有应用虚拟 DOM 的 diff 算法,之后有时间再去研究研究。