React初探

React簡(jiǎn)介

React 起源于 Facebook 的內(nèi)部項(xiàng)目岔绸,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架都不滿意,就決定自己寫(xiě)一套金句,用來(lái)架設(shè) Instagram 的網(wǎng)站方库。做出來(lái)以后渗磅,發(fā)現(xiàn)這套東西很好用真朗,就在2013年5月開(kāi)源了明未。由于 React 的設(shè)計(jì)思想極其獨(dú)特吹艇,屬于革命性創(chuàng)新,性能出眾醒叁,代碼邏輯卻非常簡(jiǎn)單坯门。所以返敬,越來(lái)越多的人開(kāi)始關(guān)注和使用椅挣,認(rèn)為它可能是將來(lái) Web 開(kāi)發(fā)的主流工具头岔。查看github

react

對(duì)ReactJS的認(rèn)識(shí)及ReactJS的優(yōu)點(diǎn)

1、ReactJS的背景和原理

Web界面由DOM樹(shù)來(lái)構(gòu)成鼠证,當(dāng)其中某一部分發(fā)生變化時(shí)峡竣,其實(shí)就是對(duì)應(yīng)的某個(gè)DOM節(jié)點(diǎn)發(fā)生了變化。在Web開(kāi)發(fā)中量九,我們需要將變化的數(shù)據(jù)實(shí)時(shí)反應(yīng)到UI上适掰,這時(shí)就需要對(duì)DOM進(jìn)行操作。而復(fù)雜或頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因荠列。React為此引入了虛擬DOM(Virtual DOM)的機(jī)制:在瀏覽器端用Javascript實(shí)現(xiàn)了一套DOM API类浪。基于React進(jìn)行開(kāi)發(fā)時(shí)所有的DOM構(gòu)造都是通過(guò)虛擬DOM進(jìn)行弯予,每當(dāng)數(shù)據(jù)變化時(shí)戚宦,React都會(huì)重新構(gòu)建整個(gè)DOM樹(shù)个曙,然后React將當(dāng)前整個(gè)DOM樹(shù)和上一次的DOM樹(shù)進(jìn)行對(duì)比锈嫩,得到DOM結(jié)構(gòu)的區(qū)別受楼,然后僅僅將需要變化的部分進(jìn)行實(shí)際的瀏覽器DOM更新。而且React能夠批處理虛擬DOM的刷新呼寸,在一個(gè)事件循環(huán)(Event Loop)內(nèi)的兩次數(shù)據(jù)變化會(huì)被合并艳汽,例如你連續(xù)的先將節(jié)點(diǎn)內(nèi)容從A變成B,然后又從B變成A对雪,React會(huì)認(rèn)為UI不發(fā)生任何變化河狐,而如果通過(guò)手動(dòng)控制,這種邏輯通常是極其復(fù)雜的瑟捣。盡管每一次都需要構(gòu)造完整的虛擬DOM樹(shù)馋艺,但是因?yàn)樘摂MDOM是內(nèi)存數(shù)據(jù),性能是極高的迈套,而對(duì)實(shí)際DOM進(jìn)行操作的僅僅是Diff部分捐祠,因而能達(dá)到提高性能的目的。這樣桑李,在保證性能的同時(shí)踱蛀,開(kāi)發(fā)者將不再需要關(guān)注某個(gè)數(shù)據(jù)的變化如何更新到一個(gè)或多個(gè)具體的DOM元素,而只需要關(guān)心在任意一個(gè)數(shù)據(jù)狀態(tài)下贵白,整個(gè)界面是如何Render的率拒。

由此我們可以看出,React的神奇之處就在于它的Virtual DOM 及 Diff算法禁荒,基于Virtual DOM猬膨,我們幾乎可以忽略性能問(wèn)題兒無(wú)所顧忌地刷新頁(yè)面,虛擬DOM機(jī)制能確保只會(huì)對(duì)頁(yè)面上真正有變化的部分進(jìn)行實(shí)際的DOM操作呛伴,而不會(huì)像傳統(tǒng)的html一樣修改整個(gè)DOM樹(shù)寥掐。關(guān)于React的Diff算法,一張圖片可以簡(jiǎn)單的解釋:

diff算法

React組件會(huì)有key屬性磷蜀,在虛擬DOM里React會(huì)對(duì)比相同Key的組件召耘,對(duì)有更新的組件進(jìn)行變更。我們可以查看Diff算法示例褐隆。也就是說(shuō)污它,與傳統(tǒng)HTML開(kāi)發(fā)不同,react只需要關(guān)注數(shù)據(jù)的整體變化而不需要數(shù)據(jù)變化產(chǎn)生的UI變化庶弃,對(duì)DOM的修改只需要交給框架衫贬,這樣就大大降低了邏輯的復(fù)雜度,降低了開(kāi)發(fā)難度歇攻。

2固惯、組件化

react的另一個(gè)特點(diǎn)就是組件化,把每一個(gè)UI單元封裝成組建的形式缴守,然后將小的組件通過(guò)組合或者嵌套的方式構(gòu)成大的組件葬毫,最終完成整體UI的構(gòu)建镇辉。組件化的思考方式不同于MVC的表現(xiàn)、控制贴捡、模型分離忽肛,React更關(guān)注的是View層,它將View層的UI按功能分成不同的組件烂斋,每個(gè)組件都是獨(dú)立的屹逛。
react組件有以下特點(diǎn):

(1)可組合(Composeable):一個(gè)組件易于和其它組件一起使用,或者嵌套在另一個(gè)組件內(nèi)部汛骂。如果一個(gè)組件內(nèi)部創(chuàng)建了另一個(gè)組件罕模,那么說(shuō)父組件擁有(own)它創(chuàng)建的子組件,通過(guò)這個(gè)特性帘瞭,一個(gè)復(fù)雜的UI可以拆分成多個(gè)簡(jiǎn)單的UI組件手销;

(2)可重用(Reusable):每個(gè)組件都是具有獨(dú)立功能的,它可以被使用在多個(gè)UI場(chǎng)景图张;

(3)可維護(hù)(MAINTAINABLE):每個(gè)小的組件僅僅包含自身的邏輯锋拖,更容易被理解和維護(hù);

擁有這些特點(diǎn)祸轮,所以ReactUI組件間的耦合性非常低兽埃。

hello world && React前奏

React的使用環(huán)境非常簡(jiǎn)單,只需要下載ReactJs,解壓后得到j(luò)s文件适袜,引入我們的html就ok柄错。

Hello World

上圖就是一個(gè)最簡(jiǎn)單的React實(shí)例,在瀏覽器頁(yè)面輸出'Hello,world!'字樣苦酱;

上面的代碼除了引進(jìn)react庫(kù)外售貌,還有一些是需要注意的:

  • 最后一個(gè)<seript>的標(biāo)簽的type屬性為text/babel。這是因?yàn)?React 獨(dú)有的 JSX 語(yǔ)法疫萤,跟 JavaScript 不兼容颂跨。凡是使用 JSX 的地方,都要加上 type="text/babel" 扯饶,當(dāng)然恒削,React并不要求一定要用jsx語(yǔ)法,也可以直接使用js編寫(xiě)尾序。

  • 引進(jìn)的三個(gè)庫(kù)必須是首先加載的钓丰,其中,react.js 是 React 的核心庫(kù)每币,react-dom.js 是提供與 DOM 相關(guān)的功能携丁,Browser.js 的作用是將 JSX 語(yǔ)法轉(zhuǎn)為 JavaScript 語(yǔ)法,這一步很消耗時(shí)間兰怠,實(shí)際上線的時(shí)候梦鉴,應(yīng)該將它放到服務(wù)器完成李茫。通過(guò)react-tools的jsx --watch src/ build/命令即可把JSX語(yǔ)法轉(zhuǎn)換為原生js。

//jsx語(yǔ)法
ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('example')
  );
//轉(zhuǎn)換后的js語(yǔ)法
ReactDOM.render(
    React.createElement("h1", null, "Hello, world!"),
    document.getElementById('example')
  );
開(kāi)始編寫(xiě)React:

相當(dāng)于main()函數(shù)的ReactDOM.render方法:

ReactDOM.render 是 React 的最基本方法尚揣,用于將模板轉(zhuǎn)為 HTML 語(yǔ)言涌矢,并插入指定的 DOM 節(jié)點(diǎn)掖举。
這里需要注意的是快骗,react并不依賴jQuery,當(dāng)然我們可以使用jQuery塔次,但是render里面第二個(gè)參數(shù)必須使用JavaScript原生的getElementByID方法方篮,不能使用jQuery來(lái)選取DOM節(jié)點(diǎn)。

JSX語(yǔ)法

JSX 是一個(gè)看起來(lái)很像 XML 的 JavaScript 語(yǔ)法擴(kuò)展励负。簡(jiǎn)單的說(shuō)藕溅,HTML 語(yǔ)言直接寫(xiě)在 JavaScript 語(yǔ)言之中,不加任何引號(hào)继榆,這就是 JSX 的語(yǔ)法巾表,它允許 HTML 與 JavaScript 的混寫(xiě),遇到 HTML 標(biāo)簽(以 < 開(kāi)頭)略吨,就用 HTML 規(guī)則解析集币;遇到代碼塊(以 { 開(kāi)頭),就用 JavaScript 規(guī)則解析翠忠,React 可以用來(lái)做簡(jiǎn)單的 JSX 句法轉(zhuǎn)換鞠苟。它能定義簡(jiǎn)潔且我們熟知的包含屬性的樹(shù)狀結(jié)構(gòu)語(yǔ)法。

jsx里既可以包含HTML標(biāo)簽也可以包含React組建秽之,區(qū)別在于当娱,渲染 HTML 標(biāo)簽,要在 JSX 里使用小寫(xiě)字母開(kāi)頭的標(biāo)簽名考榨,渲染React組建跨细,需要大寫(xiě)字母開(kāi)頭的本地變量;

JSX
由于 JSX 就是 JavaScript河质,一些標(biāo)識(shí)符像 class 和 for 不建議作為 XML 屬性名扼鞋。
作為替代,React DOM 使用 className 和 htmlFor 來(lái)做對(duì)應(yīng)的屬性愤诱。

JSX 把類 XML 的語(yǔ)法轉(zhuǎn)成純粹 JavaScript云头,XML 元素、屬性和子節(jié)點(diǎn)被轉(zhuǎn)換成 React.createElement 的參數(shù)淫半。

var Nav;
// 輸入 (JSX):
var app = <Nav color="blue" />;
// 輸出 (JS):
var app = React.createElement(Nav, {color:"blue"});

ReactJS組件

####### 組建屬性
既然ReactJS是基于組件化的開(kāi)發(fā)溃槐,所以React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標(biāo)簽一樣科吭,在網(wǎng)頁(yè)中插入這個(gè)組件昏滴。React.createClass 方法就用于生成一個(gè)組件類猴鲫。

第一個(gè)組件:

組件案例

這段代碼里有幾點(diǎn)需要注意:

1)獲取屬性的值用的是this.props.屬性名

2)創(chuàng)建的組件名稱首字母必須大寫(xiě)。

3)為元素添加css的class時(shí)谣殊,要用className拂共。

4)組件的style屬性的設(shè)置方式也值得注意,要寫(xiě)成style={{width: this.state.witdh}}姻几。

####### 組建狀態(tài)
組件免不了要與用戶互動(dòng)宜狐,React 的一大創(chuàng)新,就是將組件看成是一個(gè)狀態(tài)機(jī)蛇捌,一開(kāi)始有一個(gè)初始狀態(tài)抚恒,然后用戶互動(dòng),導(dǎo)致?tīng)顟B(tài)變化络拌,從而觸發(fā)重新渲染 UI 俭驮。下面我們來(lái)編寫(xiě)一個(gè)小例子,一個(gè)文本框和一個(gè)button春贸,通過(guò)點(diǎn)擊button可以改變文本框的編輯狀態(tài)混萝,禁止編輯和允許編輯。通過(guò)這個(gè)例子來(lái)理解ReactJS的狀態(tài)機(jī)制萍恕。先看代碼:


狀態(tài)

上面代碼是一個(gè) LikeButton 組件逸嘀,它的 getInitialState 方法用于定義初始狀態(tài),也就是一個(gè)對(duì)象雄坪,這個(gè)對(duì)象可以通過(guò) this.state 屬性讀取厘熟。當(dāng)用戶點(diǎn)擊組件,導(dǎo)致?tīng)顟B(tài)變化维哈,this.setState 方法就修改狀態(tài)值绳姨,每次修改以后,自動(dòng)調(diào)用 this.render 方法阔挠,再次渲染組件飘庄。
由于 this.props 和 this.state 都用于描述組件的特性,可能會(huì)產(chǎn)生混淆购撼。一個(gè)簡(jiǎn)單的區(qū)分方法是跪削,this.props 表示那些一旦定義,就不再改變的特性迂求,而 this.state 是會(huì)隨著用戶互動(dòng)而產(chǎn)生變化的特性碾盐。

####### 組件的生命周期
組件的生命周期分成三個(gè)狀態(tài):

Mounting:已插入真實(shí) DOM
Updating:正在被重新渲染
Unmounting:已移出真實(shí) DOM

React 為每個(gè)狀態(tài)都提供了兩種處理函數(shù),will 函數(shù)在進(jìn)入狀態(tài)之前調(diào)用揩局,did 函數(shù)在進(jìn)入狀態(tài)之后調(diào)用毫玖,三種狀態(tài)共計(jì)五種處理函數(shù)。

componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()

此外,React 還提供兩種特殊狀態(tài)的處理函數(shù)付枫。

componentWillReceiveProps(object nextProps):已加載組件收到新的參數(shù)時(shí)調(diào)用
shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時(shí)調(diào)用
組件生命周期

上面代碼在hello組件加載以后烹玉,通過(guò) componentDidMount 方法設(shè)置一個(gè)定時(shí)器,每隔100毫秒阐滩,就重新設(shè)置組件的透明度二打,從而引發(fā)重新渲染。

另外掂榔,組件的style屬性的設(shè)置方式也值得注意继效,不能寫(xiě)成

style="opacity:{this.state.opacity};"

而要寫(xiě)成

style={{opacity: this.state.opacity}}

這是因?yàn)?React 組件樣式是一個(gè)對(duì)象,所以第一重大括號(hào)表示這是 JavaScript 語(yǔ)法衅疙,第二重大括號(hào)表示樣式對(duì)象莲趣。

####### 組件的嵌套
React是基于組件化的開(kāi)發(fā)鸳慈,那么組件化開(kāi)發(fā)最大的優(yōu)點(diǎn)是什么饱溢?毫無(wú)疑問(wèn),當(dāng)然是復(fù)用走芋,下面我們來(lái)看看React中到底是如何實(shí)現(xiàn)組件的復(fù)用的绩郎,這里我們還寫(xiě)一個(gè)例子來(lái)說(shuō)吧,代碼如下:

組件嵌套
響應(yīng)結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末翁逞,一起剝皮案震驚了整個(gè)濱河市肋杖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挖函,老刑警劉巖状植,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異怨喘,居然都是意外死亡津畸,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門必怜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肉拓,“玉大人,你說(shuō)我怎么就攤上這事梳庆∨荆” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵膏执,是天一觀的道長(zhǎng)驻售。 經(jīng)常有香客問(wèn)我,道長(zhǎng)更米,這世上最難降的妖魔是什么欺栗? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上纸巷,老公的妹妹穿的比我還像新娘镇草。我一直安慰自己,他們只是感情好瘤旨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布梯啤。 她就那樣靜靜地躺著,像睡著了一般存哲。 火紅的嫁衣襯著肌膚如雪因宇。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天祟偷,我揣著相機(jī)與錄音察滑,去河邊找鬼。 笑死修肠,一個(gè)胖子當(dāng)著我的面吹牛贺辰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嵌施,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼饲化,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吗伤?” 一聲冷哼從身側(cè)響起吃靠,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎足淆,沒(méi)想到半個(gè)月后巢块,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巧号,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年族奢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裂逐。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歹鱼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卜高,到底是詐尸還是另有隱情弥姻,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布掺涛,位于F島的核電站庭敦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏薪缆。R本人自食惡果不足惜秧廉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一伞广、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疼电,春花似錦嚼锄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至修陡,卻和暖如春沧侥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背魄鸦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工宴杀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拾因。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓旺罢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親盾致。 傳聞我的和親對(duì)象是個(gè)殘疾皇子主经,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 原文地址 React 初探 [1.React 簡(jiǎn)單介紹](https://github.com/laispace/...
    賴小賴小賴閱讀 2,988評(píng)論 5 30
  • 一荣暮、why React庭惜? React是Facebook開(kāi)發(fā)的一款JS庫(kù)。React一般被用來(lái)作為MVC中的V層穗酥,它...
    amm0117閱讀 11,083評(píng)論 0 1
  • React 入門實(shí)例教程 轉(zhuǎn)載(加入了自己的一些東西护赊,推薦看原文):一看就懂的ReactJs入門教程(精華版) ...
    驀然之間的閱讀 396評(píng)論 0 0
  • 原教程內(nèi)容詳見(jiàn)精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過(guò)程中的一些閱讀筆記砾跃,個(gè)人覺(jué)得該教程講解深入淺出骏啰,比目前大...
    leonaxiong閱讀 2,810評(píng)論 1 18
  • JSX 知識(shí)準(zhǔn)備 JSX 并不是一門全新的語(yǔ)言,僅僅是一個(gè)語(yǔ)法糖抽高,允許開(kāi)發(fā)者在javascript中編寫(xiě)XML語(yǔ)言...
    艾倫先生閱讀 4,494評(píng)論 4 20