更新: 看React請看這篇的更新 http://www.cnblogs.com/sven36/p/6486860.html
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
前言:最近一直在研究React,看了陳屹先生所著的深入React技術棧,以及自己使用了這么長時間。對React應該說有比較深的理解了,正好前陣子也把兩本關於前端設計模式的書看完了,總感覺有一種知識錯綜交匯,紛紛復復在腦海里交纏的感覺,真有不吐不快之感,正好也借這幾篇博客融會貫通所學的知識。
目前手里研究的是React15.3.1這個版本,React版本更新很快,相關API的名字位置等都可能發生改變,不過其ReactElement的生成,渲染,移除等流程是不會改變的,在下希望略盡綿力希望能以管窺豹,筆力,能力所限之處,還望海涵。
首先,我想先說一說我對前端的看法,因為我之前一直在做.NET后端,剛開始的時候JS就是邊搜邊用,並沒有系統了解前端,直到一年前看了JS高級程序設計,我覺得才算真正認識了JS,后來又陸陸續續看了很多前端的書,在以前的工作中因為前端的很多邏輯都可以在后台實現,前端大部分工作都是渲染數據,操作DOM等;單獨JQuery完全可以搞定;
當然JQuery是一個非常優秀的框架,不過隨着前端工程化,規模化的趨勢越來越強;而今,以Angular,React,Vue,Node為代表這股前端的浪潮正在撲面而來,身為一個技術人員,能經歷這么一次浪潮的起伏是一次很難得的機會;
言歸正傳:那么回到React本身,React的創新性和優點在哪里呢?我個人認為是其用嵌套的JavaScript對象來表示DOM結構,即Virtual DOM並通過Virtual DOM的渲染過程把DOM操作放到內存里,在這個過程還可以實現DOM diff算法和DOM的生命周期管理;
ReactElement解析
先看一下如果按照平常的思路我們操作DOM是如何操作的,基本上就是直接innerHtml賦值,appendChild(node)或者removeChild(node);這樣寫的話效果很直接,不過也有一些缺點顯現出來:代碼沒有良好的結構,可擴展性,可維護性差;基本上就是一個DOM對象對應一個或多個DOM操作,很難復用函數;那么React是如何解決這些問題的呢?
就是用嵌套的JavaScript對象來表示DOM,那么這個JavaScript對象是如何表示的我們來調試一下:
我們先引入下載好的react.js和react-dom這兩個文件;我們通常用的JSX語法只是一個語法糖,經過靜態編譯后就會編譯成上圖React.createElement的JS調用;這里我們直接調用該方法,看看React是如何運行的;
我們看的ReactElement其實就是一個JavaScript對象,其參數主要為:$$typeof: REACT_ELEMENT_TYPE:這是ReactElement的唯一標識;
key:用來調和DOM Diff的我們先忽略它;props:我們可以看的我們傳入的DOM屬性被分析成一個對象,成為ReactElement的一個屬性;ref:是可以獲取渲染后的DOM的引用,這里我們先忽略;
type:就是傳入的標簽名,我們看的我們傳入的是div(或者是React的包裹函數);_store:是在特殊情況下做一個備份,我們先忽略它;
單有一個對象可能還不太清晰,那我們再嵌套一個對象看一下;
可以看的,父元素的props對象的一個屬性children指向了剛新建的eleChildren元素;我們用對象的形式表示出來就是:
{
$$typeof: Symbol(react.element),//ReactElement的唯一標識
_owner: null,
key: undefined,//唯一標識
props: {//屬性
children: {
$$typeof: Symbol(react.element),
_owner: null,
key: undefined,
props: {
children: "look~",
id: "reactChild"
},
ref: undefined,
type: "p"
},
id: "text",
onclick:"hello"//指向hello方法的指針
},
ref: undefined,//對DOM的引用
type: "div"//標簽類型
}
這樣的話ReactElement的結構就很清楚了,React正是通過這種對DOM的抽象,再根據不同的ReactElement生產不同的組件Component,然后遞歸渲染;
代碼我已上傳至GitHub大家可以直接在本地調試:https://github.com/sven36/React-VirtualDom
此外在ReactDOM.render()處打斷點跟進去就可以慢慢分析其如何完成事件綁定,還有其生命周期管理是如何操作的,
這些坑先挖着,以后慢慢填吧~