React是一個用于構(gòu)建UI的JS庫。你可以說它的競爭對手有AngularJS,Ember.js,Backbone和Polymer,盡管React專注的領(lǐng)域要小得多。React僅僅是MVC架構(gòu)中的V,即視圖層。
那么,React有什么特殊的呢?
React的組件使用特定的聲明式樣式書寫,不像jQuery或其它傳統(tǒng)JS庫,你不與DOM直接交互。當(dāng)背后的數(shù)據(jù)改變時,React接管所有的UI更新。
React還非???,這歸功于Virtual DOM和幕后的diff算法。當(dāng)數(shù)據(jù)改變時,React計算所需要操作的最少的DOM,然后高效的重新渲染組件。比如,如果頁面上有10000個已經(jīng)渲染的元素,但只有一個元素改變,React將僅僅更新其中一個DOM,這是React為何能高效的重新渲染整個組件的原因。
React其它令人矚目的特性包括:
我非常喜歡React v0.14 Beta 1發(fā)布中的這段話,講了React到底是什么:
現(xiàn)在我們已經(jīng)清楚,React的美妙和本質(zhì)與瀏覽器或DOM無關(guān),我們認(rèn)為React的真正基礎(chǔ)是關(guān)于組件和元素的質(zhì)樸想法:用聲明式的方式來描述任何你想渲染的東西。
在進入下一步之前,推薦你先觀看這個了不起的視頻React in 7 Minutes,它的作者是John Lindquist,推薦你訂閱PRO以獲得更多的視頻教程。
另外,也可以考慮Udemy上的這個廣受好評的教程——Build Web Apps with React JS and Flux,作者是Stephen Grider。它包含超過71個視頻和10小時以上的內(nèi)容,涵蓋了React,F(xiàn)lux,React Router,F(xiàn)irebase,Imgur API和其它。
當(dāng)學(xué)習(xí)React時,我最大的挑戰(zhàn)是使用完全不同的思考方式去構(gòu)建UI。這也是為什么你必須閱讀Thinking in React(中文版)這個官方指南的原因。
和Thinking in React中的產(chǎn)品列表風(fēng)格類似,如果我們將New Eden Faces UI分開為潛在的組件,它將會是這樣:
注意:每個組件都應(yīng)該堅持單一職責(zé)原則,如果你發(fā)現(xiàn)你的組件做的事情太多,也許最好將它分成子組件。不過話雖如此,我首先還是編寫了一個典型的的單塊組件,當(dāng)它能夠工作后,然后將它重構(gòu)為小的子組件。
在我們的項目中,頂級App組件包含Navbar,Homepage和Footer組件,Homepage組件包含兩個Character組件。
所以,無論何時你想到一個UI設(shè)計,從將它分解為不同的組件開始,并且永遠(yuǎn)考慮你的數(shù)據(jù)如何在父-子、子-父以及同胞組件間傳遞,否則你會遇到這樣的時刻:“WTF,這個到底在React里怎么實現(xiàn)的?這個用jQuery實現(xiàn)起來簡單多了……”
所以,下次你決定用React構(gòu)建一個新app時,在寫代碼之前,先畫一個這樣的層次大綱圖。它幫你視覺化多個組件間的關(guān)系,并可以照著它來構(gòu)建組件。
React中所有的組件都有render()
方法,它總是返回一個單一的子元素。因此,下面的返回語句是錯誤的,因為它返回了3個子元素。
render() {
// Invalid JSX,
return (
<li>Achura</li>
<li>Civire</li>
<li>Deteis</li>
);
}
上面的HTML標(biāo)記叫做JSX。它的語法和HTML僅有些微的不同,比如用className
代替class
,在我們開始開發(fā)應(yīng)用的時候你將會學(xué)到它的更多內(nèi)容。
當(dāng)我第一眼看到這樣的語法,我的第一反應(yīng)就是拒絕,在JavaScript中我習(xí)慣返回布爾值、數(shù)字、字符串、對象以及函數(shù),但絕不是這種東西。但是,JSX不過是一個語法糖。使用一個<ul>
標(biāo)簽包裹上面的返回內(nèi)容后,下面是不使用JSX時的模樣:
render() {
return React.createElement('ul', null,
React.createElement('li', null, 'Achura'),
React.createElement('li', null, 'Civire'),
React.createElement('li', null, 'Deteis')
);
}
我相信你會同意JSX遠(yuǎn)比普通的JavaScript的可讀性更好,另外,Babel對JSX有內(nèi)建支持,所以我們無需做任何額外的事情即可解析它。如果你用過AngularJS中的指令(directive)那么你將會欣賞React的做法,這樣你就不必同時處理兩個文件——directive.js(負(fù)責(zé)邏輯)和template.html(負(fù)責(zé)展現(xiàn)),你可以在同一個文件里同時處理邏輯和展現(xiàn)了。
React中的componentDidMount
方法和jQuery中的$(document).ready
非常相似,這個方法僅在組件第一次渲染后運行一次(只在客戶端運行),這里經(jīng)常用于初始化第三方庫和jQuery插件,或者連接到Socket.IO。
在render
方法中,你將經(jīng)常使用三元運算符:當(dāng)數(shù)據(jù)為空時隱藏元素、根據(jù)條件注入CSS類名、根據(jù)組件的狀態(tài)切換元素的展示等等。
比如下面的例子展示如果根據(jù)props值作為條件將CSS類名設(shè)為text-danger或text-success:
render() {
let delta = this.props.delta ? (
<strong className={this.props.delta > 0 ? 'text-success' : 'text-danger'}>
{this.props.delta}
</strong>
) : null;
return (
<div className='card'>
{delta}
{this.props.title}
</div>
);
}
這里我們僅僅淺嘗輒止了React的內(nèi)容,但這應(yīng)該已經(jīng)足以展示React的一般概念和它的優(yōu)點了。
React本身是非常簡單并且容易掌握的,但是,當(dāng)我們談起Flux架構(gòu)時,可能會有些麻煩。
更多建議: