preact 源码学习系列之二:组件的渲染与更新
Posted 前端控
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了preact 源码学习系列之二:组件的渲染与更新相关的知识,希望对你有一定的参考价值。
在中,我们已经掌握了“如何解析渲染一段 JSX 结构”。今天,我们进一步研究:如何解析、渲染和更新组件。
变量的解析
在研究组件解析之前,我们先来看个更简单的例子。
import {h, render, Component} from '../../preact';
class Person extends Component {
constructor() {
super();
this.state = {
name: "youngwind"
}
}
render() {
return (
<div>
{this.state.name}
</div>
)
}
}
render(<Person />, document.body);
问题:在渲染 Person 组件的时候,如何将 this.state.name 解析成真实值 "youngwind" 呢?是用正则匹配替换吗?
答案:不需要处理,因为 babel 已经帮我们处理好了。 请看编译后的代码。
由图中我们可以看出:由于 this.state.name
被当做函数参数传递给 h 函数,因此 h 函数在执行的时候会对其进行自动求值。也就是说,对于变量的解析,我们并不需要做任何特殊处理。
组件标签的解析
再看一个更复杂的例子。
import {h, render, Component} from '../../preact';
class Person extends Component {
constructor() {
super();
this.state = {
name: "youngwind",
age: 25
}
}
render() {
return (
<div>
<Name name={this.state.name}/>
<Age age={this.state.age}/>
</div>
)
}
}
class Name extends Component {
render(props) {
return (
<div>
{props.name}
</div>
)
}
}
class Age extends Component {
render(props) {
return (
<div>
{props.name}
</div>
)
}
}
render(<Person />, document.body);
编译后的代码如下:
由图中我们可以发现:babel 进行 JSX 解析时,对普通标签和组件标签的处理是类似的,只不过有两点不同。
对于组件来说,h 函数的第一个参数不是标签字符串,而是组件类;
所谓传递给组件的 props,其实就相当于给普通标签定义 attributes。
组件的渲染与更新
有了上面的基础,我们来看看如何实现组件的渲染和更新,举个例子。
import {h, render, Component} from '../../preact';
class Person extends Component {
constructor() {
super();
this.state = {
name: "youngwind",
age: 25
}
}
change() {
let {name, age} = this.state;
this.setState({
name: name + '啦',
age: age + 1
});
}
render() {
return (
<div>
<button onclick={this.change.bind(this)}>改变</button>
<Name name={this.state.name}/>
<Age age={this.state.age}/>
</div>
)
}
}
class Name extends Component {
render(props) {
return (
<div>
<label>姓名:</label>
<span>{props.name}</span>
</div>
)
}
}
class Age extends Component {
render(props) {
return (
<div>
<label>年龄:</label>
<span>{props.age}</span>
</div>
)
}
}
render(<Person />, document.body);
这段代码,我们期望的功能是:
通过 props 给 Name 和 Age 传递参数,初次渲染的时候分别显示 "youngwind" 和 "25";
点击“改变”按钮,调用 setState,触发 Name 和 Age 的重新渲染,显示 "youngwind啦" 和 "26"。
具体的实现逻辑较为繁复,难以用文字描述清楚,我画了个流程图,可以对比着我实现的代码看。
效果
最终实现的效果如下所示。(注意,效果图中控制台会输出一些生命周期的信息,这部分的代码我在 demo 中省略了,完整的代码请参考原文阅读。 )
后话
虽然在本文中已经实现了组件的更新,但是,并没有应用虚拟 DOM 的 diff 算法,之后有时间再去研究研究。
以上是关于preact 源码学习系列之二:组件的渲染与更新的主要内容,如果未能解决你的问题,请参考以下文章