更新時(shí)間:2015年12月29日15時(shí)01分 來(lái)源:傳智播客前端與移動(dòng)開(kāi)發(fā)學(xué)科 瀏覽次數(shù):
原文鏈接
http://www.csdn.net/article/2015-08-04/2825370-react
2004年,對(duì)于前端社區(qū)來(lái)說(shuō),是里程碑式的一年。Gmail橫空出世,它帶來(lái)基于前端渲染的原生應(yīng)用級(jí)別的體驗(yàn),相對(duì)于之前的服務(wù)端渲染網(wǎng)頁(yè)可謂提升了一個(gè)時(shí)代,觸動(dòng)了用戶(hù)的G點(diǎn)。自此,前端渲染的網(wǎng)站成為無(wú)數(shù)開(kāi)發(fā)者追逐的方向。
為了更好地開(kāi)發(fā)前端渲染的“原生級(jí)別的”網(wǎng)站,包括Backbone和Angular在內(nèi)的一系列前端框架應(yīng)運(yùn)而生,并迅速獲得了大規(guī)模的采用。但 是很快地,新的性能和SEO問(wèn)題也接踵而來(lái)。幾經(jīng)嘗試后,Twitter甚至從前端渲染重回服務(wù)器渲染,而Strikingly也面對(duì)過(guò)同樣棘手的問(wèn)題。
2014年,React進(jìn)入我們的視線。讓人耳目一新的是,對(duì)于其他開(kāi)源框架遇到的種種問(wèn)題,React都自信地給出了解答。幾乎沒(méi)有猶豫,我們開(kāi)始使用React來(lái)重構(gòu)Strikingly。若干年后,當(dāng)我們回望,也許會(huì)發(fā)現(xiàn),2014年也是前端社區(qū)里程碑式的一年。
React簡(jiǎn)介
React究竟是什么?Facebook把它簡(jiǎn)單低調(diào)地定義成一個(gè)“用來(lái)構(gòu)建UI的JavaScript庫(kù)”。這個(gè)定義也許會(huì)讓我們聯(lián)想到許多 JavaScript模板語(yǔ)言(比如Handlebars和Swig),或者早期的控件庫(kù)(比如YUI和Dojo),但是React所基于的幾個(gè)核心概念 使它與那些模板和控件庫(kù)迥然不同。事實(shí)上這幾個(gè)核心概念非常超前,已經(jīng)給整個(gè)前端世界帶來(lái)了沖擊性的影響。它們包括:
1. 組件和基于組件的設(shè)計(jì)流程;
2. 單向數(shù)據(jù)流動(dòng);
3. 虛擬DOM取代物理DOM作為操作對(duì)象;
4. 用JSX語(yǔ)法取代HTML模板,在JavaScript里聲明式地描述UI。
這幾條簡(jiǎn)單的原則放在一起帶來(lái)了大量的好處:
1. 前端和后端都能夠從React組件渲染頁(yè)面,完全解決了SEO長(zhǎng)期困擾JavaScript單頁(yè)應(yīng)用的問(wèn)題;
2. 我們可以簡(jiǎn)單直接地寫(xiě)前端測(cè)試而完全忘掉DOM依賴(lài);
3. 組件的封裝方式和單向數(shù)據(jù)流動(dòng)能夠極大地簡(jiǎn)化前端架構(gòu)的理解難度。
我們來(lái)看一個(gè)例子:
[js]
view plaincopy
1. var HelloMessage = React.createClass({
2. render: function() {
3. return <div>Hello {this.props.name}</div>;
4. }
5. });
6.
7. React.render(<HelloMessage name="John" />, document.body);
這個(gè)React版的Hello World已經(jīng)展現(xiàn)了React的一些核心特性。首先,HelloMessage是一個(gè)React組件;創(chuàng)建React應(yīng)用的時(shí)候,我們總是以組件為出發(fā) 點(diǎn)。每個(gè)組件的核心是一個(gè)render方法,在其中我們把這個(gè)組件的props和state拼裝到一個(gè)最終要渲染的模板中,然后返回這個(gè)模板(確切地說(shuō)這 里是一個(gè)UI描述而不是傳統(tǒng)意義上的模板)。這段代碼里看起來(lái)像HTML一樣的部分就是著名的JSX語(yǔ)法,它是在React中描述“模板”的最佳方式。
現(xiàn)在,以var開(kāi)頭的第一段里我們定義了一個(gè)叫HelloMessage的組件;下面的React.render這一行所做的,則是把這個(gè)組件渲染 到document.body里——也就是我們實(shí)際的頁(yè)面上。但在使用〈HelloMessage/〉的時(shí)候,我們做了另一件 事:name="John"??雌饋?lái)很像HTML中的元素屬性,但是既然JSX不是HTML,這個(gè)語(yǔ)法的作用是什么呢?實(shí)際上,這就是我們向React組 件傳入props的方式。回頭看第一段,我們可以看到在組件的內(nèi)部有對(duì)this.props.name的引用。這個(gè)name就是我們剛剛指定的John!
看到這里,如果你熟悉jQuery的話(huà)也許在想,這與$(document.body).html('Hello John') 有什么根本區(qū)別呢?
這就是虛擬DOM出場(chǎng)的地方了。我們像寫(xiě)HTML一樣寫(xiě)JSX,但是JSX并不會(huì)直接變成HTML和DOM。在幕后,React維護(hù)著一個(gè)虛擬 DOM,而實(shí)際上被瀏覽器直接操作的“物理”DOM只是這個(gè)虛擬DOM的投影。虛擬DOM不依賴(lài)于瀏覽器環(huán)境,它可以運(yùn)行在任何JavaScript執(zhí)行 環(huán)境。這就讓下面的代碼成為可能:
[js]
view plaincopy
1. var html =React.renderToString(<HelloMessage name="John"/>);res.send(html);
如果第二行有點(diǎn)眼熟,你沒(méi)有猜錯(cuò)——這段代碼發(fā)生在服務(wù)器端!是的,同樣的 HelloMessage,我們不僅可以讓React在前端渲染到頁(yè)面,同樣可以在后端直接渲染成HTML字符串,然后把它返回給前端。服務(wù)端預(yù)渲染就這么自然地發(fā)生了。
React帶來(lái)的革命性創(chuàng)新是前端世界過(guò)去幾年最激動(dòng)人心的變化。自從接觸React以來(lái),我們深信React會(huì)徹底改變客戶(hù)端開(kāi)發(fā)者(包括前端、 iOS和Android)的開(kāi)發(fā)體驗(yàn)。在下面的篇幅里,我們想從四個(gè)大的方向——目標(biāo)平臺(tái)(Targets)、數(shù)據(jù)處理(Data)、工具(Tools) 和新的挑戰(zhàn)——分享一下React生態(tài)系統(tǒng)和社區(qū)的進(jìn)展和未來(lái)趨勢(shì)。
目標(biāo)平臺(tái)
對(duì)于虛擬DOM的討論,很多人會(huì)說(shuō)速度快過(guò)于真正的DOM。這樣的討論可以讓人快速入門(mén)理解React,但是真正寫(xiě)過(guò)React應(yīng)用的人會(huì)明白速度 并不是虛擬DOM的精髓。我們認(rèn)為虛擬DOM的存在幫助我們做到了兩件事。第一是申明式UI。通過(guò)虛擬DOM,UI不再是一個(gè)不斷被更變的DOM,你只要 申明UI是怎么生成的,React會(huì)自動(dòng)幫你把UI的改變渲染到真正的DOM上。這種新的思維方式讓你可以不用手動(dòng)操作真正的DOM。第二是多 Target。我們一直在講Web,但React讓我們做到Web以外的Target。虛擬DOM更像是UI虛擬機(jī),自動(dòng)幫你映射到真正的實(shí)現(xiàn)上,可以是 瀏覽器DOM、iOS UI、Android UI。甚至有人做到了React映射到終端文本UI。
多Targets是React社區(qū)常常在討論的主要話(huà)題之一。多Targets的根本是提高開(kāi)發(fā)者體驗(yàn)。開(kāi)發(fā)者體驗(yàn)(DX,Developer Experience)是在React社區(qū)里屢次被提起的概念。如何在保持一樣的用戶(hù)體驗(yàn)下,提高開(kāi)發(fā)者體驗(yàn),是包括React在內(nèi)的前端社區(qū)正在思考的 問(wèn)題。事實(shí)上任何一家有多客戶(hù)端的公司都面臨著這樣同一個(gè)問(wèn)題:在各種客戶(hù)端語(yǔ)言里重新造輪子。開(kāi)發(fā)者需要學(xué)習(xí)新的語(yǔ)言、寫(xiě)和維護(hù)類(lèi)似的功能。提升客戶(hù)端 開(kāi)發(fā)者體驗(yàn)就是減少學(xué)習(xí)成本和維護(hù)成本。這就是React提倡的“Learn once,write everywhere”。
最近也有一些鼓舞人心的消息。Facebook內(nèi)部Ads Manager iOS版本由7位前端工程師用React Native花了5個(gè)月完成。而Android版本,是同一班人,3個(gè)月內(nèi)完成。代碼重用率達(dá)到了87%。
多Targets也可以是在單個(gè)平臺(tái)更深度的結(jié)合。來(lái)自React核心團(tuán)隊(duì)的Sebastian Markbåge在ReactEurope大會(huì)上給了一個(gè)讓人目瞪口呆的演講《DOM as a Second-class Citizen》。演講中他暢想React直接輸出到瀏覽器架構(gòu)的底層(圖1瀏覽器的渲染架構(gòu),圖2為Sebastian Markbåge認(rèn)為React可以做的事情)。
圖1 瀏覽器的渲染架構(gòu)
圖2 Sebastian Markbåge認(rèn)為React還可以做很多事情
姑且不談該不該這么做,通過(guò)虛擬DOM打開(kāi)了這樣的機(jī)會(huì)就已經(jīng)讓我們興奮不已了。也說(shuō)明了Facebook在設(shè)計(jì)React時(shí)已經(jīng)考慮到超越DOM。想法確實(shí)很超前。
【服務(wù)端預(yù)渲染(Pre-rendering)】
對(duì)于其他主流前端框架,頁(yè)面SEO和首次打開(kāi)速度的問(wèn)題都很讓人頭疼。Twitter當(dāng)年因?yàn)槭状未蜷_(kāi)速度過(guò)于慢甚至重回服務(wù)器渲染方案。一直以來(lái) 人們一直在尋找一種只需要編寫(xiě)一次UI組件,前后端同時(shí)都能渲染的方案。如果能做到的話(huà),我們就可以在首次打開(kāi)頁(yè)面時(shí)先用服務(wù)端渲染頁(yè)面HTML,當(dāng)瀏覽 器收到后已經(jīng)可以顯示頁(yè)面。這樣SEO和首次打開(kāi)速度都能被解決。這種完美方案社區(qū)里稱(chēng)之為Isomorphic/Universal App。
React原生支持了Pre-rendering(服務(wù)端渲染)。由于有虛擬DOM,也就意味著我們只需要后端運(yùn)行JavaScript引擎就能渲染整個(gè)DOM。目前主流后端語(yǔ)言都可以運(yùn)行V8 JavaScript引擎。比如Strikingly的后端使用Ruby on Rails,只需要使用開(kāi)源的react-rails gem就可以在Rails后端渲染前端React組件。
使用服務(wù)端渲染時(shí)要注意window和document這些瀏覽器才有的全局變量是不存在的。React組件提供這兩個(gè)lifecycle hook:componentDidMount和componentDidUpdate在服務(wù)器不會(huì)被運(yùn)行,只有在前端才會(huì)運(yùn)行。使用服務(wù)器渲染時(shí)如果要 使用任何瀏覽器才有的變量需要把代碼放到這兩個(gè)lifecycle hook定義里。
數(shù)據(jù)處理
React定義自己為MVC中的View。這讓前端開(kāi)發(fā)者從V開(kāi)始去思考UI設(shè)計(jì)。但現(xiàn)在針對(duì)數(shù)據(jù)操作和獲取方式,社區(qū)里還沒(méi)有一種公認(rèn)的方法。這也是任何寫(xiě)React應(yīng)用時(shí)最難處理的地方。
【Flux】
對(duì)于M和C,F(xiàn)acebook提出了Flux的概念。Flux是一個(gè)專(zhuān)門(mén)為React設(shè)計(jì)的應(yīng)用程序架構(gòu):應(yīng)用程序由Dispatcher、Store和View組成,其中的View就是我們的React組件。Flux的核心是如圖3所示的單向數(shù)據(jù)流動(dòng)。
圖3 單向數(shù)據(jù)流動(dòng)為Flux的核心
應(yīng)用程序中的任何一次數(shù)據(jù)變化都作為Action發(fā)起,經(jīng)過(guò)Dispatcher分發(fā)出去,被相關(guān)的Store接收到并整合,然后作為props和 state提供給View(React組件)。當(dāng)用戶(hù)在View上做了任何與數(shù)據(jù)相關(guān)的交互,View會(huì)發(fā)起新的Action,開(kāi)啟一次新的數(shù)據(jù)變化周 期。這種單向性使Flux在高層次上比傳統(tǒng)MVC架構(gòu)和以Angular和Knockout為代表的雙向數(shù)據(jù)綁定容易理解得多,大大簡(jiǎn)化了開(kāi)發(fā)者的思考和 Debug過(guò)程。
在Facebook把Flux作為一種設(shè)計(jì)模式(而不是已經(jīng)做好的框架)宣布之后,幾乎每個(gè)月出現(xiàn)一新的Flux庫(kù),他們都有各自的特色,有的對(duì)服 務(wù)器渲染支持比較好,有的運(yùn)用了更多函數(shù)式編程的概念。很多Flux庫(kù)更像是實(shí)驗(yàn),這有助于React生態(tài)的生長(zhǎng),但不可否認(rèn)的是,未來(lái)會(huì)有大量Flux 庫(kù)慢慢死去,而只有少數(shù)會(huì)存留下來(lái)或進(jìn)行合并。
【GraphQL】
在構(gòu)建大型前端應(yīng)用時(shí),前端和后端工程師通過(guò)API的方式進(jìn)行合作。API也是雙方的協(xié)議?,F(xiàn)在主流的方式是RESTful API,然而在實(shí)踐中,我們發(fā)現(xiàn)RESTful在一些真實(shí)生產(chǎn)環(huán)境的需求下不是很適用。往往我們需要構(gòu)建自定義endpoint,而這違背了 RESTful的設(shè)計(jì)理念。
舉個(gè)例子,我們想要顯示論壇帖子、作者和對(duì)應(yīng)的留言。我們分別要發(fā)出三個(gè)不同的請(qǐng)求。第二個(gè)請(qǐng)求依賴(lài)第一個(gè)請(qǐng)求結(jié)果返回的user_id,前端需要寫(xiě)代碼協(xié)調(diào)請(qǐng)求之間的依賴(lài)。分別發(fā)出三個(gè)不同請(qǐng)求在移動(dòng)端這種網(wǎng)絡(luò)不穩(wěn)定的環(huán)境下效果很不理想。
[js]
view plaincopy
1. GET /v1/posts/1
2. {
3. "id": 1,
4. "title":"React.js in Strikingly",
5. "user_id":2
6. }
[js]
view plaincopy
1. GET /v1/users/2
2. {
3. "id":2,
4. "name":"dfguo"
5. }
[js]
view plaincopy
1. GET /v1/posts/1/comments
2. [{
3. "id":6,
4. "name":"rechtar",
5. "comment":"Thanks for sharing! I would love to see some examples on GraphQL."},{
6. "id":9,
7. "name":"tengbao",
8. "comment":"I heard that you guys also use immutable.js. How did it help?"},{
9. "id":12,
10. "name":"syjstc",
11. "comment":"Impressive work! Thanks guys!"
12. },{
13. "id":18,
14. "name":"abeth86",
15. "comment":"Thanks for the sharing!"
16. }]
為解決這類(lèi)問(wèn)題,工程師會(huì)自定義一些endpoint。對(duì)于這個(gè)例子,我們可以建立一個(gè)/feeds的endpoint,集合了所有前端需要的結(jié)果:
[js]
view plaincopy
1. GET /v1/feeds/1
2. {
3. "id":1,
4. "title":"React.js in Strikingly",
5. "user":{
6. "id":2,
7. "name":"dfguo"
8. },
9. "comments":[
10. {
11. "id":6,
12. "name":"rechtar",
13. "comment":"Thanks for sharing! I would love to see some examples on GraphQL."
14. }...
15. ]
16. }
但是我們?cè)谀承﹫?chǎng)景上可能只需要post和user,不想要comments。這時(shí)難道要再定義一個(gè)feeds_without_comments 的endpoint?隨著需求的改變,自定義endpoint的方法往往使得API接口變得累贅,違背了RESTful的設(shè)計(jì)理念。而任何前端工程師需要 的數(shù)據(jù)一旦要改變都需要后端工程師的配合,這降低了產(chǎn)品的迭代速度。
來(lái)自Facebook的GraphQL是我認(rèn)為目前最接近完美的解決方法。后端工程師只需要定義可以被查詢(xún)的Type System,前端工程師就可以使用GraphQL自定義查詢(xún)。GraphQL查詢(xún)語(yǔ)句只需要形容需要返回的數(shù)據(jù)形狀:
{
post(id:1){
id,
title,
user{
id,
name
},
comments{
id,
name,
comment
}
}
}
GraphQL服務(wù)器就會(huì)返回正確的JSON格式:
[js]
view plaincopy
1. {
2. "id":1,
3. "title":"React.js in Strikingly",
4. "user":{
5. "id":2,
6. "name":"dfguo"
7. },
8. "comments":[
9. {
10. "id":6,
11. "name":"rechtar",
12. "comment":"Thanks for sharing! I would love to see some examples on GraphQL.
13. }...
14. ]
15. }
GraphQL也原生支持了API版本控制,讓你可以同時(shí)共存多個(gè)版本的客戶(hù)端(包括Web和Mobile)。這些都會(huì)減少客戶(hù)端工程師和后端工程師的耦合度,提高生產(chǎn)力。
今年7月剛推出了GraphQL的規(guī)范并開(kāi)源了JavaScript GraphQL庫(kù)。然而要讓GraphQL成為主流,F(xiàn)acebook需要打造一個(gè)像React這樣的生態(tài)系統(tǒng)。要想在你自己的應(yīng)用上用GraphQL還 必須要有后端語(yǔ)言提供GraphQL庫(kù)的支持。比如Strikingly需要GraphQL Ruby庫(kù)。這不僅僅需要前端工程師。我們認(rèn)為這將會(huì)比React生態(tài)系統(tǒng)更難建立(見(jiàn)圖4所示)。Facebook需要整個(gè)社區(qū)的參與才能達(dá)到。
圖4 GraphQL生態(tài)系統(tǒng)
【Relay】
Relay是Facebook提出的在React上應(yīng)用GraphQL的方案。React的基礎(chǔ)單位是組件(Component),構(gòu)建大型應(yīng)用就 是組合和嵌套組件。以組件為單位的設(shè)計(jì)模式是目前社區(qū)里最認(rèn)可的,這也是前端世界的趨勢(shì)之一。每個(gè)組件需要的數(shù)據(jù)也應(yīng)該在組件內(nèi)部定義。Relay讓組件 可以自定義其所需要GraphQL數(shù)據(jù)格式,在組件實(shí)例化的時(shí)候再去GraphQL服務(wù)器獲取數(shù)據(jù)。Relay也會(huì)自動(dòng)構(gòu)建嵌套組件的GraphQL查 詢(xún),這樣多個(gè)嵌套的組件只需要發(fā)一次請(qǐng)求。Relay將會(huì)在8月份開(kāi)源。
【Immutability】
React社區(qū)接受了很多函數(shù)式編程的想法,其中受Clojure影響很深。對(duì)Immutable數(shù)據(jù)的使用就是來(lái)自Clojure社區(qū)。當(dāng)年 Om,這個(gè)用ClojureScript寫(xiě)的React wrapper在速度上居然完虐原生JavaScript版本的React。這讓整個(gè)社區(qū)都震驚了。其中一個(gè)原因就是ClojureScript使用了 Immutable數(shù)據(jù)。React社區(qū)里也冒出了Immutable.js,這讓JavaScript里也能使用Immutable數(shù)據(jù),完美彌補(bǔ)了 JavaScript在負(fù)責(zé)數(shù)據(jù)對(duì)象比較的先天性不足。Immutable.js也成為了構(gòu)建大型React應(yīng)用的必備。甚至有在討論是否把 Immutable.js直接納入JavaScript語(yǔ)言中。我們認(rèn)為小型應(yīng)用不會(huì)遇到虛擬DOM的性能瓶頸,引入Immutable.js只會(huì)讓數(shù)據(jù) 操作很累贅。
工具
工欲善其事,必先利其器。React的火爆得力于來(lái)自社區(qū)的工具,而React也推動(dòng)了這些工具的進(jìn)步。這里我們想介紹幾個(gè)React社區(qū)里比較受歡迎的工具。
【W(wǎng)ebpack】
在React里,由于需要用到JSX,使用Webpack或Browserify這類(lèi)工具編譯代碼已經(jīng)漸漸成為前端工程師工作流程的一部分。Webpack是一款強(qiáng)大的前端模塊管理和打包工具(見(jiàn)圖5所示)。這里列出它的一些特性:
1. 同時(shí)支持CommonJS和AMD模塊;
2. 靈活和可擴(kuò)展的Loader(加載器)機(jī)制,例如提供對(duì)JSX、ES6、Less的支持;
3. 支持對(duì)CSS,圖片等其他資源進(jìn)行打包;
4. 可以基于配置和智能分析打包成多個(gè)文件;
5. 內(nèi)置強(qiáng)大的Code Splitting功能可以拆分并動(dòng)態(tài)加載包;
6. 開(kāi)發(fā)模式支持Hot Module Replacement模式,提高開(kāi)發(fā)效率。
圖5 前端模塊管理和打包工具Webpack
【Babel】
ECMAScript 6(ES6)規(guī)范在今年四月剛敲定,React社區(qū)基本全面擁抱ES6。但目前還有很多瀏覽器不支持ES6。使用像Webpack這樣的工具編譯代碼使得 我們可以在開(kāi)發(fā)時(shí)使用ES6(或者更新版本),在上線前編譯成ES5。編譯工具中最引人注意的是Babel。前身為ES6to5,Babel是目前社區(qū)最 火的ES6編譯到ES5的代碼工具,F(xiàn)acebook團(tuán)隊(duì)甚至已經(jīng)決定轉(zhuǎn)用Babel而不再維護(hù)之前內(nèi)部使用的jstranform。通過(guò)Loader機(jī) 制,Webpack可以非常簡(jiǎn)易地和Babel結(jié)合應(yīng)用。
【React-hot-reload】
在開(kāi)發(fā)任何大型前端應(yīng)用過(guò)程中,我們常常會(huì)因?yàn)橐恍┬″e(cuò)誤就需要重新刷新整個(gè)頁(yè)面。React-hot-reload嘗試解決這個(gè)問(wèn)題,提高開(kāi)發(fā)效率。他使用了Webpack的Hot Module Replacement功能,動(dòng)態(tài)替換React組件的lifecycle hook定義,不用刷新頁(yè)面也可以更新代碼變化。
【React Developer Tool】
這款Facebook官方推出的Chrome插件可以讓你方便地在瀏覽器中直接查看React的組件結(jié)構(gòu)。安裝后,在Chrome開(kāi)發(fā)者工具中會(huì)多出一個(gè)React Tab。界面就像DOM Inspector一樣,只不過(guò)是看React組件結(jié)構(gòu)關(guān)系。是開(kāi)發(fā)React應(yīng)用不可多得的工具之一。
挑戰(zhàn)
React正在快速開(kāi)拓著它的疆界,這意味在獲得新的喜悅的同時(shí),我們也面臨著許多新的挑戰(zhàn)?,F(xiàn)在圍繞著幾個(gè)大的議題,React社區(qū)仍沒(méi)有達(dá)成定論,每周甚至每天都有新的實(shí)驗(yàn)項(xiàng)目在嘗試這些問(wèn)題的解決。
【動(dòng)畫(huà)】
一直以來(lái)大家都對(duì)動(dòng)畫(huà)應(yīng)該在React里怎么表達(dá)為狀態(tài)感到困惑。Cheng Lou的React Tween State是我們認(rèn)為最符合React思維的做法。把位移存在State里,然后通過(guò)JavaScript動(dòng)態(tài)渲染新的位置。不過(guò)大家對(duì)該做法是否能達(dá)到 滿(mǎn)意的速度一直持有保留態(tài)度。在今年ReactEurope的演講中,他為我們展現(xiàn)出了出色的效果和速度,非常值得一看。
在Strikingly,我們對(duì)于動(dòng)畫(huà)則采取了比較實(shí)用主義的處理方式:我們定義了一些容器組件,比如〈JQFade/〉和〈JQSlide/〉, 在其中調(diào)用jQuery的動(dòng)畫(huà)方法來(lái)實(shí)現(xiàn)相應(yīng)的Transition。這種方式在理論上并不完全符合React的精神,不過(guò)到現(xiàn)在為止還是能夠滿(mǎn)足我們需 求的。
【Flux庫(kù)與Relay】
正如上文已經(jīng)提到過(guò)的,目前Flux的各種實(shí)現(xiàn)可謂是百花齊放,其中還并沒(méi)有出現(xiàn)一個(gè)具有權(quán)威性的事實(shí)標(biāo)準(zhǔn)。Relay同樣也是剛剛孵化不久的新生概念——所有這些意味著雖然Flux+Relay會(huì)帶來(lái)生產(chǎn)力的飛升,要實(shí)際用上它們我們還要待以時(shí)日。
【CSS】
CSS是一個(gè)有趣的話(huà)題:似乎所有人都覺(jué)得當(dāng)前的CSS有深刻的缺陷,但是對(duì)于怎么解決這些缺陷大家的意見(jiàn)卻分成了兩派各不相讓?zhuān)阂慌烧J(rèn)為CSS “可以被修好”,并且致力于修好它,由此誕生了cssnext這樣的項(xiàng)目;另一派認(rèn)為CSS從根本上作為誕生于一個(gè)古老時(shí)代的東西,已經(jīng)不能適應(yīng)大規(guī)模、 組件化的現(xiàn)代開(kāi)發(fā)流程,這一思想集中反映在Christopher Chedeau的演講《React: CSS in JS》中;在其中他提出了CSS的七個(gè)根本問(wèn)題,然后指出在JavaScript中直接使用inline CSS可以幾乎“免費(fèi)”地解決所有這些問(wèn)題。在傳統(tǒng)的Web開(kāi)發(fā)最佳實(shí)踐中inline CSS一直是被壓制的反面實(shí)踐,現(xiàn)在我們卻能夠以一個(gè)全新的視角看待它,這也完美地例證了React真的是在給整個(gè)前端世界帶來(lái)根本性的推動(dòng)。
總結(jié)
在不久前的JSConf 2015上赫門(mén)提出了前端的摩爾定理:前端每18月會(huì)難一倍。前端之所以變化這么快,是因?yàn)槲覀儸F(xiàn)在面臨著前所未有的工程化挑戰(zhàn)。今天的前端復(fù)雜度跟幾年 前完全不是一個(gè)等級(jí)。這也促使社區(qū)要找到在這種復(fù)雜度下能保持開(kāi)發(fā)效率和開(kāi)發(fā)體驗(yàn)的工具和設(shè)計(jì)模式。React社區(qū)從其他領(lǐng)域(游戲渲染、 ClojureScript、函數(shù)式編程)偷師學(xué)藝,結(jié)合前端面臨的獨(dú)特問(wèn)題,提出了一系列解決方案。React社區(qū)在各方面都推動(dòng)著前端社區(qū)往前進(jìn)。這 對(duì)整個(gè)社區(qū)都是好事。我們也希望前端各個(gè)框架可以互相學(xué)習(xí),共同推動(dòng)整個(gè)社區(qū)的發(fā)展。