Vitrual DOM
在web开发中我们总需要将变化的数据实时反应到ui上,这时就需要对dom进行操作。
而复杂或频繁的DOM操作通常是性能瓶颈产生的原因(如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标)。
React为此引入了虚拟DOM(virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API.
基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。
而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A变成B,然后又从B变成A,React会认为UI不发生任何变化,如果通过手动控制,这种逻辑通常是极其复杂的。
尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操作的仅仅是Diff部分,因而能达到提高性能的目的。
react是如何处理事件的?
react的事件是合成事件,内部原理非常复杂,我们这里只把关键性,可以用来解答这个问题的原理部分进行介绍即可。
jsx实际是函数提供的语法糖,那么这段jsx代码:
<buttont onClick = {this.handleClick}>
Click me
</button>
会被转化为:
React.createElement("button",{
onClick:this.handleClick
},"Click me")
react在组件加载和更新时,将事件通过统一注册到上,然后会有一个事件池存储了所有的事件,当事件触发的时候,通过进行事件分发。
所以可以简单的理解为,最终会作为一个回调函数调用。
setState相关
- 为什么要setState,而不是直接this.state.xx == oo;
setState做的事情不仅仅只是修改了的值,另外最重要的是它会触发React的更新机制,会进行diff,然后将patch部分更新到真实dom里。如果直接的话,state的值确实会改,但是改了不会触发ui的更新,那就不是数据驱动了。 - setState是同步还是异步相关的问题
state的更新,react可能会把多个调用合并成一个调用。
因为 和 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
要解决这个问题,可以让接收一个函数而不是一个对象。
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
使用React Fragments 避免额外标记
用户创建组件时,每个组件应具有单个父标签。父级不能有两个标签,所以顶部要有一个公共标签。这个额外标签除了充当组件的。因此,我们可以将元素包含在片段中。
export default class NestComponet extends React.Component{
render(){
return (
<>
<h1>This is the Header component</h1>
<h2>Welcome to demo page</h2>
</>
)
}
}
上面的代码没有额外的标记,因此的工作量。