自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ReactJS :我就是想把代碼和HTML混在一起!

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

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

從他們的表情看,我就能猜出來(lái)這兩個(gè)家伙又在抱怨人心不古,世風(fēng)日下,沒(méi)有程序員使用他們了。

旁邊是jQuery和ExtJS, 他倆在低聲交談,時(shí)不時(shí)朝JSP和ASP方向看兩眼, 我估計(jì)jQuery又在宣傳他那DOM操作大法了。

幸好,還有一個(gè)靠窗的空桌,有兩個(gè)座位, 我走過(guò)去坐下,要了一杯咖啡,拿起一本雜志,邊喝邊看。 

[[238363]]

代碼中混雜HTML

這時(shí)候又進(jìn)來(lái)一個(gè)年輕人,看到我這一桌還有空位,不客氣地坐下, 掏出一張紙,爬在桌子上刷刷刷地寫(xiě)代碼。

我偷偷看了一眼,不由得大吃一驚: 怎么能在代碼中寫(xiě)HTML呢?

  1. function Welcome(props) {     
  2.     return <h1>Hello, {props.name}</h1>; 

這時(shí)候服務(wù)員正好走過(guò)來(lái)送咖啡, 也注意到了這段代碼, 大叫道:“我賽,這都什么年代了,還在代碼里寫(xiě)HTML !”

這一下便炸了鍋,ASP, JSP, jQuery, ExtJS等紛紛圍過(guò)來(lái)看個(gè)究竟。

在代碼中寫(xiě)HTML,我記得這是上個(gè)世紀(jì)90年代的事情,那時(shí)候連ASP,JSP都沒(méi)有,只好用C語(yǔ)言寫(xiě)CGI代碼,HTML就混雜在C代碼中,類(lèi)似這樣:

  1. void main(){ 
  2.     char content[MAXLINE]; 
  3.     sprintf(content,"<html>"); 
  4.     sprintf(content,"<head>"); 
  5.     sprintf(content,"<title>Homepage</title>"); 
  6.     sprintf(content,"</head>");  
  7.     ......其他內(nèi)容略......  
  8.     printf("Content-length : %d \r\n",(int)strlen(content)); 
  9.     printf("Content-type:text/html \r\n\r\n"); 
  10.     printf("%s",content); 
  11.     fflush(stdout); 
  12.     exit(0); 

這種模式給修改界面和業(yè)務(wù)邏輯帶來(lái)了巨大的麻煩,等到ASP, JSP這樣的“模板”語(yǔ)言出現(xiàn)以后,變成了在HTML中寫(xiě)代碼: 

UI設(shè)計(jì)師先把HTML頁(yè)面整體設(shè)計(jì)好,交給程序員再用<%..%>在其中填入動(dòng)態(tài)的部分, 這種方式可以讓設(shè)計(jì)師和程序員更好地合作。

  1. <%@ Language="VBScript" %> 
  2. <html> 
  3. <head><title>我的主頁(yè)</title></head> 
  4. <body> 
  5. <% For i=3 to 5 %> 
  6. <font size=<%=i%> > 
  7.     你好,歡迎來(lái)到我的主頁(yè)。 
  8. </font> <br /> 
  9. <% Next %> 
  10. </body> 
  11. </html> 

現(xiàn)在又有人想在代碼中寫(xiě)HTML,簡(jiǎn)直是瘋了!

模板 vs 組件

看到這么多人圍過(guò)來(lái), 小伙子漲紅了臉:“我這不是HTML,我這個(gè)是JSX,是JavaScript的一個(gè)語(yǔ)法擴(kuò)展,你們仔細(xì)看看,其實(shí)和ASP的模板也很像的。”

<h1>Hello, {props.name}</h1>

“那你為什么不直接用模板,為什么要把HTML放到JavaScript當(dāng)中?這是我們?cè)缇蛼仐壍姆茨J剑?rdquo;  ASP問(wèn)道。

“對(duì)啊,為什么不用模板? ”  周?chē)娜艘搽S聲附和。

“因?yàn)槲矣X(jué)得模板難于復(fù)用!” 小伙子突然大聲說(shuō)道。

說(shuō)起復(fù)用,這一點(diǎn)我的體會(huì)太深了,在開(kāi)發(fā)中,我通常把描述界面結(jié)構(gòu)的HTML,描述展示的CSS, 和操作DOM的JavaScript放在不同的文件當(dāng)中,在運(yùn)行時(shí)把他們結(jié)合起來(lái), 但是這種分離只是技術(shù)層面分開(kāi)管理而已,在邏輯上并沒(méi)有實(shí)現(xiàn)高耦合的組件,也就無(wú)法復(fù)用。

“我想了一個(gè)新的辦法,” 小伙子繼續(xù)說(shuō)道,“組件化,我們可以創(chuàng)建一個(gè)個(gè)的組件,然后讓這些組件組合起來(lái)形成一個(gè)完整的Web界面。 就像我剛寫(xiě)的組件Welcome,可以復(fù)用的,可以用在Web頁(yè)面的任何地方。”

“組件? 這小子有點(diǎn)想法。” ASP說(shuō)道,“我表哥Visual Basic 就有很多組件,奧,好像大家叫他控件,在開(kāi)發(fā)一個(gè)應(yīng)用的時(shí)候,只需要把控件拖拽到表單界面上,設(shè)置屬性,編寫(xiě)對(duì)事件的處理代碼就可以了,非常簡(jiǎn)單快速。”

“你怎么沒(méi)給我說(shuō)過(guò)?” JSP表示不滿, 他和ASP在90年代打得你死我活,現(xiàn)在拋棄了門(mén)戶之見(jiàn),成了好基友。

小伙子向ASP投去感激的目光,找到支持支持者了。

沒(méi)想到ASP馬上潑了一盆冷水:“不過(guò)控件是在桌面應(yīng)用使用的,在Web開(kāi)發(fā)中我們不這么干,它和桌面應(yīng)用差別太大,實(shí)現(xiàn)不了。”

小伙子馬上反駁:“怎么實(shí)現(xiàn)不了,一個(gè)組件不就是一個(gè)可以復(fù)用的單元嗎? 在Web頁(yè)面上, 這個(gè)組件要像桌面應(yīng)用那樣,負(fù)責(zé)自己的展示和行為,有屬性可以設(shè)置,有方法可以調(diào)用,對(duì)外可以響應(yīng)事件(Event), 對(duì)內(nèi)可以維護(hù)組件狀態(tài)。”

我說(shuō)道:“你說(shuō)說(shuō)你那個(gè)Welcome組件具體怎么復(fù)用?”

小伙子說(shuō): “很簡(jiǎn)單,在JSX中,那個(gè)Welcome組件就像普通的HTML標(biāo)簽一樣,直接就可以使用了!”

  1. function App(props){ 
  2.   return
  3.     <div>      
  4.       <Welcome name="碼農(nóng)翻身" /> 
  5.       <Welcome name="張大胖" />       
  6.     </div> 
  7.   ); 

確實(shí)是不錯(cuò),這些自定義的標(biāo)簽(組件),可以一層層地組合起來(lái),構(gòu)建成一個(gè)大的頁(yè)面。

有狀態(tài)的組件

還是jQuery經(jīng)驗(yàn)老道,他瞇著眼看了半天,開(kāi)始發(fā)難:“你號(hào)稱是組件,但組件都是有內(nèi)部狀態(tài)的,而你這代碼就是一個(gè)函數(shù)而已,一個(gè)輸入,一個(gè)輸出,根本不是組件!”

小伙子說(shuō):“你說(shuō)得沒(méi)錯(cuò),那個(gè)組件是個(gè)無(wú)狀態(tài)的組件,只有輸入和輸出,我給你看個(gè)有狀態(tài)的組件。”

  1. class Counter extends React.Component{ 
  2.    constructor(props){ 
  3.      super(props); 
  4.      this.state = {count : 0}; 
  5.    } 
  6.    handleClick(){ 
  7.      this.setState({count: this.state.count + 1}); 
  8.    } 
  9.    render(){ 
  10.      return ( 
  11.        <div> 
  12.          <button onClick={(e) => this.handleClick(e)}>Click!</button> 
  13.          <h3> 
  14.            Click Count : {this.state.count
  15.          </h3> 
  16.        </div> 
  17.      ); 
  18.    } 
  19.  } 

這個(gè)組件一下子就復(fù)雜多了,似乎是一個(gè)繼承了Component的類(lèi),有構(gòu)造器,有函數(shù),還有個(gè)返回HTML的render方法。

小伙子說(shuō):“看到?jīng)]有,這是一個(gè)用來(lái)計(jì)數(shù)的小組件, 數(shù)值被保存起來(lái)了,就是那個(gè) this.state.count ,初始值為0, 每次點(diǎn)擊就會(huì)調(diào)用this.setState函數(shù),把count 加一。”

小伙子說(shuō)著在瀏覽器中給我們展示了一下效果,果然,每次點(diǎn)擊,Count數(shù)都會(huì)變化。

我們看了以后都有一個(gè)感覺(jué),這確實(shí)是一個(gè)組件,你看它內(nèi)部有展示的邏輯,有狀態(tài),有操作,自己的活兒自己干。

“state ? 你不是有props嗎? 還用state ? ” ExtJS 看到j(luò)Query沉默了,馬上為朋友兩肋插刀。

小伙子說(shuō)道:“是這樣的,我用props 來(lái)保存從上層組件(父組件)傳遞過(guò)來(lái)的數(shù)據(jù),用state來(lái)保存本組件的內(nèi)部數(shù)據(jù)。”

jQuery道:“父組件可以用props給子組件傳遞數(shù)據(jù),那子組件如果想把數(shù)據(jù)告訴父組件,該怎么處理?”

小伙子向jQuery投去佩服的目光, 回答道:“這個(gè)問(wèn)題我想過(guò)了,父組件可以用props傳遞一個(gè)'鉤子'函數(shù)給子組件,在必要的時(shí)候,子組件就調(diào)用這個(gè)函數(shù),把數(shù)據(jù)告知父組件。”

UI = render(data)

jQuery不甘心,想了一會(huì)兒,又拋出一個(gè)重磅炸彈:“怪哉怪哉,從你這個(gè)Counter組件中,怎么看不到對(duì)DOM的操作? 如果沒(méi)有DOM操作,你怎么實(shí)現(xiàn)點(diǎn)擊了Click! 按鈕以后,下面的數(shù)目發(fā)生變化的? ”

jQuery是操作DOM的高手,什么鏈?zhǔn)秸{(diào)用了,選擇器了被他玩得賊溜,現(xiàn)在看到Counter組件中連一行DOM操作的代碼都沒(méi)有,顛覆了自己的人生觀,肯定要弄個(gè)究竟。

“我估計(jì)大家都用JavaScript操作過(guò)DOM,說(shuō)實(shí)話,很簡(jiǎn)單,很直觀,可是當(dāng)項(xiàng)目變得復(fù)雜以后, 當(dāng)頁(yè)面上的事件處理多了以后, JavaScript的代碼會(huì)和DOM緊密地糾纏在一起,就不好維護(hù)了。”  小伙子說(shuō)道。

大家都紛紛點(diǎn)頭。

“所以呢, 所以我就想辦法把他屏蔽了,在我這里,不用操作DOM,只要你調(diào)用setState方法,我發(fā)現(xiàn)數(shù)據(jù)發(fā)生了變化,我就會(huì)渲染整個(gè)頁(yè)面。所以對(duì)程序員來(lái)講,在概念上非常簡(jiǎn)單,只需要setState,剩下的操作都交給我。 用個(gè)公式來(lái)表達(dá)就是 UI = render(data) 。  ”

“嘶.....”    聽(tīng)到這個(gè)“渲染整個(gè)頁(yè)面”,大家伙都倒吸了一口涼氣。如果一個(gè)頁(yè)面有很多數(shù)據(jù),現(xiàn)在只改變了一個(gè)小小的count的數(shù)值 ,難道還要把其他的也全部渲染一遍?

看到大家疑惑的表情,小伙子笑了笑,解釋道:“全部渲染是從概念上來(lái)說(shuō)的,在實(shí)現(xiàn)層面,還是局部更新。為了實(shí)現(xiàn)這一點(diǎn),我特意實(shí)現(xiàn)了一個(gè)虛擬的DOM。”

“每次數(shù)據(jù)發(fā)生了變化,我會(huì)比較兩個(gè)虛擬DOM的區(qū)別,找到那些數(shù)據(jù)真正發(fā)生改變的地方,然后操作真正的DOM, 這樣以來(lái),其實(shí)真正的更新還是局部的。”

看到了虛擬DOM, 大家都明白這小伙子絕對(duì)不是一般人了!。

但是看到那混雜著代碼和HTML的,試圖改變Web開(kāi)發(fā)方式的“組件”,都覺(jué)得不可思議,難以接受,搖著頭,慢慢地散開(kāi)了。

ASP一邊走一邊給JSP說(shuō):“這玩意兒,太顛覆了,根本不會(huì)有人用。”

JSP同意:“是啊,我們還是玩模板去吧。”

人走得差不多了,我問(wèn)小伙子:“你叫什么名字? ”

“ReactJS。”

“有沒(méi)有興趣到我們公司工作? ” 我遞上了我的名片,上面印著我們公司的Logo : Facebook。

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)作者微信公眾號(hào)coderising獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專欄
相關(guān)推薦

2013-08-06 09:49:01

2018-02-01 21:18:40

戴爾

2016-09-02 16:49:54

APPVR

2011-01-20 11:42:49

同事

2015-10-20 16:48:06

AnsibleDocker可擴(kuò)展設(shè)計(jì)

2016-08-12 09:49:06

Intel

2009-11-06 08:57:31

WCF開(kāi)發(fā)

2009-07-22 09:29:44

ScalaSpiral程序

2015-03-05 10:27:56

蘋(píng)果IBM

2022-05-06 14:19:02

邊緣計(jì)算物聯(lián)網(wǎng)5G

2021-03-15 10:26:29

邊緣計(jì)算云計(jì)算混合云

2015-11-16 17:13:05

巴黎恐怖襲擊互聯(lián)網(wǎng)公司

2015-11-12 10:23:35

5G物聯(lián)網(wǎng)

2015-02-09 19:49:19

暢捷通

2015-04-22 17:22:05

eBay京東

2019-01-03 13:58:53

人工智能大數(shù)據(jù)數(shù)據(jù)分析

2020-09-16 11:20:40

PythonBashLinux

2017-11-15 08:26:52

IntelAMD技術(shù)

2020-11-30 10:30:01

神經(jīng)網(wǎng)絡(luò)感知機(jī)中間層

2021-04-12 18:03:39

Nginx架構(gòu)負(fù)載
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)