一 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值,並進行相關操作