新聞中心
當(dāng)我走進(jìn)這個著名的咖啡館,這里已經(jīng)有很多人了,我環(huán)顧四周,看到遠(yuǎn)處的JSP同學(xué)和ASP同學(xué)正聊得火熱,他倆,還有今天沒看見的Velocity同學(xué)每次都會占據(jù)最里邊的座位,似乎故意要逃避大家。

創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè),為客戶提供做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)開發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類網(wǎng)站都可以開發(fā),成都品牌網(wǎng)站建設(shè),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢,價(jià)格優(yōu)惠,收費(fèi)合理。
從他們的表情看,我就能猜出來這兩個家伙又在抱怨人心不古,世風(fēng)日下,沒有程序員使用他們了。
旁邊是jQuery和ExtJS, 他倆在低聲交談,時(shí)不時(shí)朝JSP和ASP方向看兩眼, 我估計(jì)jQuery又在宣傳他那DOM操作大法了。
幸好,還有一個靠窗的空桌,有兩個座位, 我走過去坐下,要了一杯咖啡,拿起一本雜志,邊喝邊看。
代碼中混雜HTML
這時(shí)候又進(jìn)來一個年輕人,看到我這一桌還有空位,不客氣地坐下, 掏出一張紙,爬在桌子上刷刷刷地寫代碼。
我偷偷看了一眼,不由得大吃一驚: 怎么能在代碼中寫HTML呢?
- function Welcome(props) {
- return
Hello, {props.name}
;- }
這時(shí)候服務(wù)員正好走過來送咖啡, 也注意到了這段代碼, 大叫道:“我賽,這都什么年代了,還在代碼里寫HTML !”
這一下便炸了鍋,ASP, JSP, jQuery, ExtJS等紛紛圍過來看個究竟。
在代碼中寫HTML,我記得這是上個世紀(jì)90年代的事情,那時(shí)候連ASP,JSP都沒有,只好用C語言寫CGI代碼,HTML就混雜在C代碼中,類似這樣:
- void main(){
- char content[MAXLINE];
- sprintf(content,"");
- sprintf(content,"");
- sprintf(content,"
Homepage ");- sprintf(content,"");
- ......其他內(nèi)容略......
- printf("Content-length : %d \r\n",(int)strlen(content));
- printf("Content-type:text/html \r\n\r\n");
- printf("%s",content);
- fflush(stdout);
- exit(0);
- }
這種模式給修改界面和業(yè)務(wù)邏輯帶來了巨大的麻煩,等到ASP, JSP這樣的“模板”語言出現(xiàn)以后,變成了在HTML中寫代碼:
UI設(shè)計(jì)師先把HTML頁面整體設(shè)計(jì)好,交給程序員再用<%..%>在其中填入動態(tài)的部分, 這種方式可以讓設(shè)計(jì)師和程序員更好地合作。
- <%@ Language="VBScript" %>
我的主頁 - <% For i=3 to 5 %>
- >
- 你好,歡迎來到我的主頁。
- <% Next %>
- }
現(xiàn)在又有人想在代碼中寫HTML,簡直是瘋了!
模板 vs 組件
看到這么多人圍過來, 小伙子漲紅了臉:“我這不是HTML,我這個是JSX,是JavaScript的一個語法擴(kuò)展,你們仔細(xì)看看,其實(shí)和ASP的模板也很像的?!?/p>
Hello, {props.name}
“那你為什么不直接用模板,為什么要把HTML放到JavaScript當(dāng)中?這是我們早就拋棄的反模式!” ASP問道。
“對啊,為什么不用模板? ” 周圍的人也隨聲附和。
“因?yàn)槲矣X得模板難于復(fù)用!” 小伙子突然大聲說道。
說起復(fù)用,這一點(diǎn)我的體會太深了,在開發(fā)中,我通常把描述界面結(jié)構(gòu)的HTML,描述展示的CSS, 和操作DOM的JavaScript放在不同的文件當(dāng)中,在運(yùn)行時(shí)把他們結(jié)合起來, 但是這種分離只是技術(shù)層面分開管理而已,在邏輯上并沒有實(shí)現(xiàn)高耦合的組件,也就無法復(fù)用。
“我想了一個新的辦法,” 小伙子繼續(xù)說道,“組件化,我們可以創(chuàng)建一個個的組件,然后讓這些組件組合起來形成一個完整的Web界面。 就像我剛寫的組件Welcome,可以復(fù)用的,可以用在Web頁面的任何地方?!?/p>
“組件? 這小子有點(diǎn)想法?!?ASP說道,“我表哥Visual Basic 就有很多組件,奧,好像大家叫他控件,在開發(fā)一個應(yīng)用的時(shí)候,只需要把控件拖拽到表單界面上,設(shè)置屬性,編寫對事件的處理代碼就可以了,非常簡單快速?!?/p>
“你怎么沒給我說過?” JSP表示不滿, 他和ASP在90年代打得你死我活,現(xiàn)在拋棄了門戶之見,成了好基友。
小伙子向ASP投去感激的目光,找到支持支持者了。
沒想到ASP馬上潑了一盆冷水:“不過控件是在桌面應(yīng)用使用的,在Web開發(fā)中我們不這么干,它和桌面應(yīng)用差別太大,實(shí)現(xiàn)不了?!?/p>
小伙子馬上反駁:“怎么實(shí)現(xiàn)不了,一個組件不就是一個可以復(fù)用的單元嗎? 在Web頁面上, 這個組件要像桌面應(yīng)用那樣,負(fù)責(zé)自己的展示和行為,有屬性可以設(shè)置,有方法可以調(diào)用,對外可以響應(yīng)事件(Event), 對內(nèi)可以維護(hù)組件狀態(tài)。”
我說道:“你說說你那個Welcome組件具體怎么復(fù)用?”
小伙子說: “很簡單,在JSX中,那個Welcome組件就像普通的HTML標(biāo)簽一樣,直接就可以使用了!”
- function App(props){
- return(
- );
- }
確實(shí)是不錯,這些自定義的標(biāo)簽(組件),可以一層層地組合起來,構(gòu)建成一個大的頁面。
有狀態(tài)的組件
還是jQuery經(jīng)驗(yàn)老道,他瞇著眼看了半天,開始發(fā)難:“你號稱是組件,但組件都是有內(nèi)部狀態(tài)的,而你這代碼就是一個函數(shù)而已,一個輸入,一個輸出,根本不是組件!”
小伙子說:“你說得沒錯,那個組件是個無狀態(tài)的組件,只有輸入和輸出,我給你看個有狀態(tài)的組件。”
- class Counter extends React.Component{
- constructor(props){
- super(props);
- this.state = {count : 0};
- }
- handleClick(){
- this.setState({count: this.state.count + 1});
- }
- render(){
- return (
- Click Count : {this.state.count}
- );
- }
- }
這個組件一下子就復(fù)雜多了,似乎是一個繼承了Component的類,有構(gòu)造器,有函數(shù),還有個返回HTML的render方法。
小伙子說:“看到?jīng)]有,這是一個用來計(jì)數(shù)的小組件, 數(shù)值被保存起來了,就是那個 this.state.count ,初始值為0, 每次點(diǎn)擊就會調(diào)用this.setState函數(shù),把count 加一?!?/p>
小伙子說著在瀏覽器中給我們展示了一下效果,果然,每次點(diǎn)擊,Count數(shù)都會變化。
我們看了以后都有一個感覺,這確實(shí)是一個組件,你看它內(nèi)部有展示的邏輯,有狀態(tài),有操作,自己的活兒自己干。
“state ? 你不是有props嗎? 還用state ? ” ExtJS 看到j(luò)Query沉默了,馬上為朋友兩肋插刀。
小伙子說道:“是這樣的,我用props 來保存從上層組件(父組件)傳遞過來的數(shù)據(jù),用state來保存本組件的內(nèi)部數(shù)據(jù)。”
jQuery道:“父組件可以用props給子組件傳遞數(shù)據(jù),那子組件如果想把數(shù)據(jù)告訴父組件,該怎么處理?”
小伙子向jQuery投去佩服的目光, 回答道:“這個問題我想過了,父組件可以用props傳遞一個'鉤子'函數(shù)給子組件,在必要的時(shí)候,子組件就調(diào)用這個函數(shù),把數(shù)據(jù)告知父組件?!?/p>
UI = render(data)
jQuery不甘心,想了一會兒,又拋出一個重磅炸彈:“怪哉怪哉,從你這個Counter組件中,怎么看不到對DOM的操作? 如果沒有DOM操作,你怎么實(shí)現(xiàn)點(diǎn)擊了Click! 按鈕以后,下面的數(shù)目發(fā)生變化的? ”
jQuery是操作DOM的高手,什么鏈?zhǔn)秸{(diào)用了,選擇器了被他玩得賊溜,現(xiàn)在看到Counter組件中連一行DOM操作的代碼都沒有,顛覆了自己的人生觀,肯定要弄個究竟。
“我估計(jì)大家都用JavaScript操作過DOM,說實(shí)話,很簡單,很直觀,可是當(dāng)項(xiàng)目變得復(fù)雜以后, 當(dāng)頁面上的事件處理多了以后, JavaScript的代碼會和DOM緊密地糾纏在一起,就不好維護(hù)了?!? 小伙子說道。
大家都紛紛點(diǎn)頭。
“所以呢, 所以我就想辦法把他屏蔽了,在我這里,不用操作DOM,只要你調(diào)用setState方法,我發(fā)現(xiàn)數(shù)據(jù)發(fā)生了變化,我就會渲染整個頁面。所以對程序員來講,在概念上非常簡單,只需要setState,剩下的操作都交給我。 用個公式來表達(dá)就是 UI = render(data) 。 ”
“嘶.....” 聽到這個“渲染整個頁面”,大家伙都倒吸了一口涼氣。如果一個頁面有很多數(shù)據(jù),現(xiàn)在只改變了一個小小的count的數(shù)值 ,難道還要把其他的也全部渲染一遍?
看到大家疑惑的表情,小伙子笑了笑,解釋道:“全部渲染是從概念上來說的,在實(shí)現(xiàn)層面,還是局部更新。為了實(shí)現(xiàn)這一點(diǎn),我特意實(shí)現(xiàn)了一個虛擬的DOM。”
“每次數(shù)據(jù)發(fā)生了變化,我會比較兩個虛擬DOM的區(qū)別,找到那些數(shù)據(jù)真正發(fā)生改變的地方,然后操作真正的DOM, 這樣以來,其實(shí)真正的更新還是局部的?!?/p>
看到了虛擬DOM, 大家都明白這小伙子絕對不是一般人了!。
但是看到那混雜著代碼和HTML的,試圖改變Web開發(fā)方式的“組件”,都覺得不可思議,難以接受,搖著頭,慢慢地散開了。
ASP一邊走一邊給JSP說:“這玩意兒,太顛覆了,根本不會有人用。”
JSP同意:“是啊,我們還是玩模板去吧?!?/p>
人走得差不多了,我問小伙子:“你叫什么名字? ”
“ReactJS?!?/p>
“有沒有興趣到我們公司工作? ” 我遞上了我的名片,上面印著我們公司的Logo : Facebook。
【本文為專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】
戳這里,看該作者更多好文
網(wǎng)站欄目:ReactJS:我就是想把代碼和HTML混在一起!
本文網(wǎng)址:http://www.5511xx.com/article/dphipdh.html


咨詢
建站咨詢
