Skip to main content

Rendering

高性能的虚拟 DOM 渲染

DOM element ( Document Object Model )

文档对象模型(DOM)是一个网络文档的编程接口。它代表页面,以便程序可以改变文档的结构、风格和内容。DOM 将文档表示为节点和对象;这样,编程语言就可以与页面交互。

列表渲染

列表渲染,即对于很多结构上重复的内容,可以通过循环的方式来渲染每一个元素

state = {
tags: ["tag1", "tag2", "tag3"],
};

对于以上的列表,可以使用 map 函数来进行简单的列表渲染,代码如下。其中要求 key 的值必须唯一

// map函数用法
// map((pram1,pram2)=> <li key={pram1}>{pram2}</li>)

<ul>
{this.state.tags.map((tag) => (
<li key={tag}>{tag}</li>
))}
</ul>

条件渲染

根据状态不同,去修改某个元素的状态(比如切换颜色)

// 通过判断state.count的值来切换其显示对应的类
getClassName() {
let classes = "badge badge-pill m-2 badge-";
classes += this.state.count === 0 ? "info" : "warning";
return classes;
}

// 可以在render中直接这样调用
<span className={this.getClassName()}></span>

Handling Events

状态更新与重新渲染

更新 state 并重新渲染界面

想象中的逻辑如下所示,直接 this.state+=1

increment(){
this.state.count+=1;
}

然后在 button 中直接像这样绑定过去

<button onClick="{this.increment}">test</button>

但是这里会出现两个问题

首先是 this 指针的问题。在 React 中,如果直接调用 ans = function() ,那么在 function 中的 this 指针是可以正常指向当前对象的。但是在这里我们传入的是函数本身 onClick = increment,会丢失掉 this 绑定对象的信息。

func = increment   # 直接引用函数,函数体内不可以直接用this指针
ans = increment() # 调用函数,函数体内可以直接用this指针

其次,这种方式并不会重新渲染页面。也就是说,如果 this.state.count 是要显示在界面上的,就算点击了 这个 increment 的 button , 前端显示也不会改变

note

this.state.count 是可以正常+1 的,如果不需要这个数字展示给用户,就无所谓了

接着来分别解决这两个问题

this 指针问题

解决办法有两个。其一为重写 constructor ,在实例化对象前,进行显式绑定

// 构造函数中显式绑定
constructor() {
super();
this.increment = this.increment.bind(this);
}

increment(){
this.count+=1;
};

第二种方式是使用箭头函数,它具有更简洁的语法结构,并且会自动绑定执行上下文

// 箭头函数
increment = () => {
this.state.count += 1;
};

笔者这里更推荐后者,这样更简便,但是过多的箭头函数可能会降低代码可读性,请酌情选择。无论选择哪种,都可以解决我们的问题,都可以直接使用onClick = {this.increment}绑定

重新渲染问题

React 为我们写好了 setState 接口,对于需要在修改后重新渲染的变量,我们可以直接使用 this.setState() 来更新数据。其参数为字典型,只需要为 this.state 的子集即可,也就是说可以只修改部分变量

increment(){
this.setState({ count: this.state.count + 1 });
}

最终解决办法

综上所述,如下的代码则是最终解决方法。完美解决了 this 指针和重新渲染的问题

increment = () => {
this.setState({ count: this.state.count + 1 });
};
Buy me a coffee ☕: