一 jsx 的本质是什么?
jsx是语法糖,需要被编译成js才能运行。
jsx 看似是html 结构,实质是js结构的语法糖,在代码编译阶段被编译成js结构。所以jsx的本质可描述为看似html结构的js结构。
jsx是独立的标准,可被其他项目使用(pReact)
//编译前的jsx
<div>
<ul className='list'>
list.map((item,index)=>{return(<li key={index}>{item}</li>)})
</ul>
</div>
//编译后的 jsx代码
React.createElement('div',null,React.createElement('ul',,{className:'list'},
list.map((item,index)=>{return React.createElement('li',{key:index},item)})))
二 jsx 的语法
1.可以在jsx语法中进行注释 {/
/}2.标签,js表达式,判断,循环,事件绑定
三 jsx 和 vdom的关系
jsx中运用了vdom,由于jsx的实质是js,js要转化为html再渲染到界面上,数据驱动视图的改变 正好是vdom擅长的事情
React.createElement 和 h函数都生成了虚拟dom,区别是 React.createElement可以对自定义的组件进行解析 ,解析的顺序为:初始化实例,然后再调用实例的render函数
React中的虚拟dom 何时渲染到界面上,何时进行虚拟dom的diff比较
初次渲染:ReactDOM.render(
更新渲染:setState时候,进行虚拟dom的比较并更新视图; // patch(vdom,newVdom);
setState 是异步还是同步?
既可以是异步也可以是同步,在React的合成函数 和 钩子函数中表现为异步,在原生函数或者setTimeout,setInterval的函数中表现为同步。(即在React可监测的函数中为异步,不能监测的函数中表现为同步)。
我认为 setState函数的本质是同步的,只是在合成函数 或 钩子函数中对setState进行了特殊的处理,让其表现为异步更新状态。
为什么要让setState表现为异步呢?
节约性能,用户同时调用多个setState时候,异步调用setState可进行多个setState的合并,防止多次进行视图的渲染浪费性能。
setState 修改完状态之后,会调用renderComponent函数(继承自React.Component)进行patch(vdom,newVdom)更新视图
// 模拟 React.Component 中的 renderComponent
class Component {
constructor(){}
renderComponent(){
const preVnode = this._vnode;
const newVnode = this.render();
patch(preVnode,newVnode);
this._vnode = newVnode;
}
}
// renderComponent 在setState更新状态之后调用来更新视图
this.setState({
list:[1,2,3]
},()=>{this.rednerComponent()})
注:setState的第二个参数可以传递进去一个回调函数,可获取改变之后的state值,并进行相关操作