react.js基礎

現在最熱門的前端框架有AngularJS、React、Bootstrap等。自從接觸了ReactJS,ReactJs的虛擬DOM(Virtual?DOM)和組件化的開發深深的吸引了我,下面來跟我一起領略ReactJs的風采吧~~ 文章有點長,耐心讀完,你會有很大收獲哦~

?一、ReactJS簡介

  React 起源于 Facebook 的內部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網站。做出來以后,發現這套東西很好用,就在2013年5月開源了。由于?React?的設計思想極其獨特,屬于革命性創新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關注和使用,認為它可能是將來?Web?開發的主流工具。

ReactJS官網地址:http://facebook.github.io/react/

?

Github地址:https://github.com/facebook/react

?

?二、對ReactJS的認識及ReactJS的優點

?首先,對于React,有一些認識誤區,這里先總結一下:

  • React不是一個完整的MVC框架,最多可以認為是MVC中的V(View),甚至React并不非常認可MVC開發模式;
  • React的服務器端Render能力只能算是一個錦上添花的功能,并不是其核心出發點,事實上React官方站點幾乎沒有提及其在服務器端的應用;
  • 有人拿React和Web?Component相提并論,但兩者并不是完全的競爭關系,你完全可以用React去開發一個真正的Web?Component;
  • React不是一個新的模板語言,JSX只是一個表象,沒有JSX的React也能工作。

1、ReactJS的背景和原理

  在Web開發中,我們總需要將變化的數據實時反應到UI上,這時就需要對DOM進行操作。而復雜或頻繁的DOM操作通常是性能瓶頸產生的原因(如何進行高性能的復雜DOM操作通常是衡量一個前端開發人員技能的重要指標)。React為此引入了虛擬DOM(Virtual DOM)的機制:在瀏覽器端用Javascript實現了一套DOM API。基于React進行開發時所有的DOM構造都是通過虛擬DOM進行,每當數據變化時,React都會重新構建整個DOM樹,然后React將當前整個DOM樹和上一次的DOM樹進行對比,得到DOM結構的區別,然后僅僅將需要變化的部分進行實際的瀏覽器DOM更新。而且React能夠批處理虛擬DOM的刷新,在一個事件循環(Event Loop)內的兩次數據變化會被合并,例如你連續的先將節點內容從A變成B,然后又從B變成A,React會認為UI不發生任何變化,而如果通過手動控制,這種邏輯通常是極其復雜的。盡管每一次都需要構造完整的虛擬DOM樹,但是因為虛擬DOM是內存數據,性能是極高的,而對實際DOM進行操作的僅僅是Diff部分,因而能達到提高性能的目的。這樣,在保證性能的同時,開發者將不再需要關注某個數據的變化如何更新到一個或多個具體的DOM元素,而只需要關心在任意一個數據狀態下,整個界面是如何Render的。

如果你像在90年代那樣寫過服務器端Render的純Web頁面那么應該知道,服務器端所要做的就是根據數據Render出HTML送到瀏覽器端。如果這時因為用戶的一個點擊需要改變某個狀態文字,那么也是通過刷新整個頁面來完成的。服務器端并不需要知道是哪一小段HTML發生了變化,而只需要根據數據刷新整個頁面。換句話說,任何UI的變化都是通過整體刷新來完成的。而React將這種開發模式以高性能的方式帶到了前端,每做一點界面的更新,你都可以認為刷新了整個頁面。至于如何進行局部更新以保證性能,則是React框架要完成的事情。

  借用Facebook介紹React的視頻中聊天應用的例子,當一條新的消息過來時,傳統開發的思路如上圖,你的開發過程需要知道哪條數據過來了,如何將新的DOM結點添加到當前DOM樹上;而基于React的開發思路如下圖,你永遠只需要關心數據整體,兩次數據之間的UI如何變化,則完全交給框架去做。可以看到,使用React大大降低了邏輯復雜性,意味著開發難度降低,可能產生Bug的機會也更少。

?

2、組件化

  虛擬DOM(virtual-dom)不僅帶來了簡單的UI開發邏輯,同時也帶來了組件化開發的思想,所謂組件,即封裝起來的具有獨立功能的UI部件。React推薦以組件的方式去重新思考UI構成,將UI上每一個功能相對獨立的模塊定義成組件,然后將小的組件通過組合或者嵌套的方式構成大的組件,最終完成整體UI的構建。例如,Facebook的instagram.com整站都采用了React來開發,整個頁面就是一個大的組件,其中包含了嵌套的大量其它組件,大家有興趣可以看下它背后的代碼。

如果說MVC的思想讓你做到視圖-數據-控制器的分離,那么組件化的思考方式則是帶來了UI功能模塊之間的分離。我們通過一個典型的Blog評論界面來看MVC和組件化開發思路的區別。

對于MVC開發模式來說,開發者將三者定義成不同的類,實現了表現,數據,控制的分離。開發者更多的是從技術的角度來對UI進行拆分,實現松耦合。

對于React而言,則完全是一個新的思路,開發者從功能的角度出發,將UI分成不同的組件,每個組件都獨立封裝。

在React中,你按照界面模塊自然劃分的方式來組織和編寫你的代碼,對于評論界面而言,整個UI是一個通過小組件構成的大組件,每個組件只關心自己部分的邏輯,彼此獨立。

React認為一個組件應該具有如下特征:

(1)可組合(Composeable):一個組件易于和其它組件一起使用,或者嵌套在另一個組件內部。如果一個組件內部創建了另一個組件,那么說父組件擁有(own)它創建的子組件,通過這個特性,一個復雜的UI可以拆分成多個簡單的UI組件;

(2)可重用(Reusable):每個組件都是具有獨立功能的,它可以被使用在多個UI場景;

(3)可維護(Maintainable):每個小的組件僅僅包含自身的邏輯,更容易被理解和維護;

?

?二、下載ReactJS,編寫Hello,world

?  ReactJs下載非常簡單,為了方便大家下載,這里再一次給出下載地址http://facebook.github.io/react/downloads.html,下載完成后,我么看到的是一個壓縮包。解壓后,我們新建一個html文件,引用react.js和JSXTransformer.js這兩個js文件。html模板如下(js路徑改成自己的):

復制代碼
<!DOCTYPE html>
<html><head><script src="build/react.js"></script><script src="build/JSXTransformer.js"></script></head><body><div id="container"></div><script type="text/jsx">// ** Our code goes here! **</script></body>
</html>
復制代碼

  這里大家可能會奇怪,為什么script的type是text/jsx,這是因為 React 獨有的 JSX 語法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/jsx" 。 其次,React 提供兩個庫: react.js 和 JSXTransformer.js ,它們必須首先加載。其中,JSXTransformer.js 的作用是將 JSX 語法轉為 JavaScript 語法。這一步很消耗時間,實際上線的時候,應該將它放到服務器完成。

到這里我們就可以開始編寫代碼了,首先我們先來認識一下ReactJs里面的React.render方法:

React.render 是 React 的最基本方法,用于將模板轉為 HTML 語言,并插入指定的 DOM 節點。

下面我們在script標簽里面編寫代碼,來輸出Hello,world,代碼如下:

React.render(<h1>Hello, world!</h1>,document.getElementById('container'));

這里需要注意的是,react并不依賴jQuery,當然我們可以使用jQuery,但是render里面第二個參數必須使用JavaScript原生的getElementByID方法,不能使用jQuery來選取DOM節點。

?然后,在瀏覽器打開這個頁面,就可以看到瀏覽器顯示一個大大的Hello,world,因為我們用了<h1>標簽。

到這里,恭喜,你已經步入了ReactJS的大門~~下面,讓我們來進一步學習ReactJs吧~~

?

?三、Jsx語法

?  HTML 語言直接寫在 JavaScript 語言之中,不加任何引號,這就是 JSX 的語法,它允許 HTML 與 JavaScript 的混寫,了解過AngularJs的看到下面的代碼一定會感覺很熟悉的,我們來看代碼:

復制代碼
var names = ['Jack', 'Tom', 'Alice'];React.render(<div>{names.map(function (name) {return <div>Hello, {name}!</div>})}</div>,document.getElementById('container'));
復制代碼

這里我們聲明了一個names數組,然后遍歷在前面加上Hello,輸出到DOM中,輸出結果如下:

JSX 允許直接在模板插入 JavaScript 變量。如果這個變量是一個數組,則會展開這個數組的所有成員,代碼如下:

復制代碼
var arr = [<h1>Hello world!</h1>,<h2>React is perfect!</h2>,];React.render(<div>*{arr}*</div>,document.getElementById('container'));
復制代碼

顯示結果如下:

這里的星號只是做標識用的,大家不要被她迷惑了~~

?你看到這里,說明你對React還是蠻感興趣的,恭喜你,堅持下來了,那么下面,我們開始學習React里面的"真功夫"了~~ Are you ready?

?

?四、ReactJS組件

1、組件屬性?

  前面說了,ReactJS是基于組件化的開發,下面我們開始來學習ReactJS里面的組件,React?允許將代碼封裝成組件(component),然后像插入普通?HTML?標簽一樣,在網頁中插入這個組件。React.createClass?方法就用于生成一個組件類。

下面,我們來編寫第一個組件Greet,有一個name屬性,然后輸出hello + name的值,代碼如下:

復制代碼
var Greet = React.createClass({render: function() {return <h1>Hello {this.props.name}</h1>;}});React.render(<Greet name="Jack" />,document.getElementById('container'));
復制代碼

看到這段代碼,接觸過AngularJS的朋友們是不是有一種熟悉的感覺,不過這里有幾點需要注意:

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

  2、創建的組件名稱首字母必須大寫。

  3、為元素添加css的class時,要用className.

  4、組件的style屬性的設置方式也值得注意,要寫成style={{width: this.state.witdh}}

?

2、組件狀態

  組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然后用戶互動,導致狀態變化,從而觸發重新渲染 UI 。下面我們來編寫一個小例子,一個文本框和一個button,通過點擊button可以改變文本框的編輯狀態,禁止編輯和允許編輯。通過這個例子來理解ReactJS的狀態機制。先看代碼:

復制代碼
var InputState = React.createClass({getInitialState: function() {return {enable: false};},handleClick: function(event) {this.setState({enable: !this.state.enable});},render: function() {return (<p><input type="text" disabled={this.state.enable} /><button onClick={this.handleClick}>Change State</button></p>);}});React.render(<InputState />,document.getElementById('container'));
復制代碼

這里,我們又使用到了一個方法getInitialState,這個函數在組件初始化的時候執行,必需返回NULL或者一個對象。這里我們可以通過this.state.屬性名來訪問屬性值,這里我們將enable這個值跟input的disabled綁定,當要修改這個屬性值時,要使用setState方法。我們聲明handleClick方法,來綁定到button上面,實現改變state.enable的值.效果如下:

原理分析:

?  當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以后,自動調用 this.render 方法,再次渲染組件。

這里值得注意的幾點如下:

  1、getInitialState函數必須有返回值,可以是NULL或者一個對象。

  2、訪問state的方法是this.state.屬性名。

  3、變量用{}包裹,不需要再加雙引號。

?

3、組件的生命周期  

組件的生命周期分成三個狀態:

  • Mounting:已插入真實?DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真實 DOM

React?為每個狀態都提供了兩種處理函數,will?函數在進入狀態之前調用,did?函數在進入狀態之后調用,三種狀態共計五種處理函數。

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

此外,React 還提供兩種特殊狀態的處理函數。

  • componentWillReceiveProps(object nextProps):已加載組件收到新的參數時調用
  • shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時調用

?

下面來看一個例子:

復制代碼
 var Hello = React.createClass({getInitialState: function () {return {opacity: 1.0};},componentDidMount: function () {this.timer = setInterval(function () {var opacity = this.state.opacity;opacity -= .05;if (opacity < 0.1) {opacity = 1.0;}this.setState({opacity: opacity});}.bind(this), 100);},render: function () {return (<div style={{opacity: this.state.opacity}}>Hello {this.props.name}</div>);}});React.render(<Hello name="world"/>,document.body);
復制代碼

上面代碼在hello組件加載以后,通過 componentDidMount 方法設置一個定時器,每隔100毫秒,就重新設置組件的透明度,從而引發重新渲染。

?

4、組件的嵌套

  React是基于組件化的開發,那么組件化開發最大的優點是什么?毫無疑問,當然是復用,下面我們來看看React中到底是如何實現組件的復用的,這里我們還寫一個例子來說吧,代碼如下:

復制代碼
var Search = React.createClass({render: function() {return (<div>{this.props.searchType}:<input type="text" /><button>Search</button></div>);}});var Page = React.createClass({render: function() {return (<div><h1>Welcome!</h1><Search searchType="Title" /><Search  searchType="Content" /></div>);}});React.render(<Page />,document.getElementById('container'));
復制代碼

這里我們創建了一個Search組件,然后又創建了一個Page組件,然后我們在Page組件中調用Search組件,并且調用了兩次,這里我們通過屬性searchType傳入值,最終顯示結果如圖:

?

?五、ReactJs小結

關于ReactJS今天就先學習到這里了,下面來總結一下,主要有以下幾點:

  1、ReactJs是基于組件化的開發,所以最終你的頁面應該是由若干個小組件組成的大組件。

  2、可以通過屬性,將值傳遞到組件內部,同理也可以通過屬性將內部的結果傳遞到父級組件(留給大家研究);要對某些值的變化做DOM操作的,要把這些值放到state中。

  3、為組件添加外部css樣式時,類名應該寫成className而不是class;添加內部樣式時,應該是style={{opacity: this.state.opacity}}而不是style="opacity:{this.state.opacity};"。

  4、組件名稱首字母必須大寫。

  5、變量名用{}包裹,且不能加雙引號。

?

?六、參考資料

React中文文檔 ?http://reactjs.cn/

React 入門實例教程 ? ?http://www.ruanyifeng.com/blog/2015/03/react.html

顛覆式前端UI開發框架:React ??http://www.infoq.com/cn/articles/subversion-front-end-ui-development-framework-react

轉載于:https://www.cnblogs.com/qingkun/p/10855510.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536468.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536468.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536468.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第 11 章 日志管理 - 089 - 初探 ELK

在開源的日志管理方案中&#xff0c;最出名的莫過于 ELK 了。 ELK 是三個軟件的合稱&#xff1a;Elasticsearch、Logstash、Kibana。 Elasticsearch 一個近乎實時查詢的全文搜索引擎。Elasticsearch 的設計目標就是要能夠處理和搜索巨量的日志數據。 Logstash 讀取原始日志&…

【轉】Kotlin 新版來了,支持跨平臺!

作者&#xff1a;Tamic 原文鏈接&#xff1a;juejin.im/post/5cd8f9… 谷歌在今年的 I/O 大會上宣布&#xff0c;Kotlin 編程語言現在是 Android 應用程序開發人員的首選語言(谷歌宣布 Kotlin 成為安卓開發首選)。 還有一個好消息, Kotlin 1.3.30 正式發布&#xff0c;做了對ap…

WebSocket輕松單臺服務器5w并發jmeter實測

測試結論 nginx最多只能維持(65535*后端服務器IP個數)條websocket的長連接&#xff0c;如果后端websocket服務器IP只有一個&#xff0c;那么就只能最多支持65535條連接。瓶頸就產生在了nginx上建議采用LVS的DR模式來做負載均衡&#xff0c;這樣最大長連接數目就只和websocket服…

人工智能的歷史

AI(Artificial Intelligence)即人工智能&#xff0c;最初是在1956 年被提出&#xff0c;人工智能研究如何用計算機去模擬、延伸和擴展人的智能&#xff1b;如何把計算機用得更聰明&#xff1b;如何設計和建造具有高智能水平的計算機應用系統&#xff1b;如何設計和制造更聰明的…

nginx配置 vue打包后的項目 解決刷新頁面404問題|nginx配置多端訪問

訪問vue頁面時&#xff0c;/# 使url看著不美觀&#xff0c;使用 H5 history模式可以完美解決這個問題&#xff0c;但需要后端nginx幫助。接下來我們自己配置一下。 使用前端路由&#xff0c;但切換新路由時&#xff0c;想要滾動到頁面頂部&#xff0c;或者保持原先的滾動位置&a…

算法導論2nd 10.1-7

為什么80%的碼農都做不了架構師&#xff1f;>>> 思路&#xff1a;兩個隊列q1和q2&#xff0c;兩個隊列指針pusher和poper分別指向q1和q2&#xff0c;push時調用pusher->enqueue&#xff0c;然后將poper里的元素全部dequeue并enqueue到pusher&#xff0c;最后交換…

阿里云Windows2012 R2服務器IPV6配置記錄

要上蘋果APP&#xff0c;則必須要支持IPV6和HTTPS&#xff0c;阿里云本身沒有開放IPV6地址。因此需要進行IPV6的相關配置。查了很多IPV6的配置資料&#xff0c;最終選擇用HE進行IPV6設置。在這過程中遇到一些問題&#xff0c;以記錄下來以備注。 1、IPV6 Tunnel Broker設置 在H…

mycat 1.6.5 for mysql 8分表攻略

2019獨角獸企業重金招聘Python工程師標準>>> 簡述 mycat 對于 mysql 的支持有版本要求&#xff0c;目前 1.6.5 不支持 mysql 8.0 版本。因為mysql 8.0 的加密方式發生了變化。 mycat 1.6.5 連接 mysql 8.0 的兩個方式 mysql 8.0 采用兼容方式&#xff0c;&#xff0…

Funcode-貪吃蛇

自己編寫的一個小游戲&#xff0c;本來打算做貪吃蛇&#xff0c;結果不會使蛇的身子隨蛇頭方向改變而改變就換了種想法&#xff0c;最后變成了這樣一個另類的小游戲&#xff0c;“笑哭“&#xff0c;下面是程序的主要代碼&#xff0c;如果有興趣也可以下載完整程序代碼資源&…

mac 使用遠程連接

https://www.jianshu.com/p/9cc90361f37a轉載于:https://www.cnblogs.com/xiangsj/p/10876400.html

systemtap執行過程中報probe timer.profile registration error

probe timer.profile registration error 今天在執行火焰圖的過程中&#xff0c;代碼報錯&#xff0c;probe timer.profile registration error 經過查詢、分析可能是在該平臺該函數是不安全、不共享的。 將 probe timer.profile { 用該代碼替換即可 probe perf.sw.cpu_clock !…

(十三)java版spring cloud+spring boot+redis社交電子商務平臺-springboot集成spring cache...

電子商務社交平臺源碼請加企鵝求求&#xff1a;一零三八七七四六二六。本文介紹如何在springboot中使用默認的spring cache&#xff0c;聲明式緩存Spring 定義 CacheManager 和 Cache 接口用來統一不同的緩存技術。例如 JCache、 EhCache、 Hazelcast、 Guava、 Redis 等。在使…

搭建gitlab及部署gitlab-runner

2019獨角獸企業重金招聘Python工程師標準>>> 1、搭建gitlab,之前yum安裝gitlab,安裝后一直報502錯誤,網上百度試過還是無法使用; 所以這次部署在docker里面;如下命令&#xff1a; docker run --detach --hostname gitlab.forebix.com --publish 4433:443 --publish …

母牛的故事

母牛的故事 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Description 有一對夫婦買了一頭母牛&#xff0c;它從第2年起每年年初生一頭小母牛。每頭小母牛從第四個年頭開始&#xff0c;每年年初也生一頭小母牛。請編程實現在第n年的時候…

軟件性能測試

通常&#xff0c;衡量一個軟件系統性能的常見指標有&#xff1a; 1、響應時間&#xff08;服務器端響應時間、網絡響應時間、客戶端響應時間&#xff09; 那客戶感受的響應時間其實是等于客戶端服務器端網絡響應時間 2、吞吐量 軟件系統在每單位時間內能處理多少個事務/請求/單…

王小二切餅

王小二切餅 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Description 王小二自夸刀工不錯&#xff0c;有人放一張大的煎餅在砧板上&#xff0c;問他&#xff1a;“餅不許離開砧板&#xff0c;切n(1<n<100)刀最多能分成多少塊&…

SmoothNLP 中文NLP文本處理工具 Python 實戰示范

SmoothNLP pythonJavaPython python interfaces for SmoothNLP 的 Python 接口&#xff0c; 支持自動下載底層jar包 &#xff0c;目前支持Python3 Pypi 官方安裝 pip3 install smoothnlp 復制代碼請注意使用python3安裝smoothnlp項目&#xff0c;當前版本 version0.2.4 如果您使…

本地緩存Caffeine

Caffeine 說起Guava Cache&#xff0c;很多人都不會陌生&#xff0c;它是Google Guava工具包中的一個非常方便易用的本地化緩存實現&#xff0c;基于LRU算法實現&#xff0c;支持多種緩存過期策略。由于Guava的大量使用&#xff0c;Guava Cache也得到了大量的應用。但是&#x…

《圖解HTTP》核心知識總結

HTTP協議的簡介 HTTP是超文本傳輸協議&#xff0c;用于客戶端和服務器端之間的通信&#xff0c;屬于TCP/IP中的應用層。 HTTP協議的基礎知識 客戶端和服務器端 客戶端是服務請求方&#xff0c;服務器端是服務提供方。 URI和URL URI:URI是統一資源標識符&#xff1b; URL:是統一…

1042: 篩法求素數

1042: 篩法求素數 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 1387 Solved: 918 [Submit][Status][Web Board] Description 用篩法求之N內的素數。 Input N Output 0&#xff5e;N的素數 Sample Input 100 Sample Output 2 3 5 7 11 13 17 19 23 29 31 37 4…