怎樣用React JS構建一個用戶界面?本文將快速地給你一個React JS的概覽。代碼,請君移步react-starterjavascript
React只有不多的API,這使得它很容易去學習與理解。固然,使用它也是至關有意思的。可是,簡約卻並不簡單。在咱們開始以前,有一些概念是須要去理解的。html
React元素是用於呈現HTML結構的JavaScript對象。它們不會存在於瀏覽器中,只是用於描述瀏覽器中的元素,好比h1
, div
或者 section
等等。java
模塊是開發者建立的React元素。它們經過比用戶界面的範圍要大,由於它們同時包含了其結構與功能。想像一下導航欄,點贊按鈕,圖片上傳這些模塊的概念。react
JSX是一種用於建立React元素和模塊的技術,或者說是規範、語言。好比 <h1>Hello</h1>
即是一個用JSX所寫的React元素。一樣的React元素,能夠用原生的JavaScript實現,即 React.DOM.h1(null, 'Hello');
。相比原生的JavaScript,JSX更加簡潔。會讓你花更少的精力去讀和寫代碼,在上線的時候將其轉換成原生的JavaScript便可。git
虛擬DOM是一個JavaScript的樹形結構,包含了React元素和模塊。React經過渲染虛擬DOM到瀏覽器,使得用戶界面得以顯示。React也會觀察虛擬DOM的變化,根據虛擬DOM自動地改變瀏覽器DOM元素。github
瞭解了這些概念以後,咱們就能夠暢快地敲React代碼了。這裏將會建立一系列的用戶界面,每個界面都將提早添加一層功能層。咱們會作一個相似instagram的應用 - 固然,這個很粗糙。數組
業務的第一步是渲染一個虛擬的元素(React元素或者模塊均可以)。因爲每個虛擬元素都存在於內存之中,因此咱們必須顯式地告訴React,將其渲染到瀏覽器的DOM之中。瀏覽器
React.render(<img src='http://owenyang0.github.io/img/background.jpg' />, document.body);
render
函數接受兩個參數,一個是虛擬元素,一個是真實的DOM節點。React就是獲取到虛擬元素以後,將其插入到所給的節點之中。此時,在瀏覽器中即可以看到照片了。dom
模塊是React的核心與靈魂。它們能夠自定義React元素。常常由單一的功能或者結構擴展而來。函數
var Photo = React.createClass({ render: function() { return <img src='http://owenyang0.github.io/img/background.jpg' /> } }); React.render(<Photo />, document.body);
createClass
函數接受一個對象,該對象實現了render
的函數。
這個Photo
模塊被構建好,<Photo />
,而後渲染到document body中。
該模塊並無比上一個React圖像元素作更多的事情,但這卻更加有利於在功能和結構上進行擴展。
屬性能夠認爲是模塊的一些配置選項。它們以參數(arguments)的形式傳遞給模塊,看起來就像HTML的屬性(attributes)。
var Photo = React.createClass({ render: function() { return ( <div className='photo'> <img src={this.props.imageURL} /> <span>{this.props.caption}</span> </div> ) } }); React.render(<Photo imageURL='http://owenyang0.github.io/img/background.jpg' caption='Headset' />, document.body);
在render
函數裏面,兩個屬性(props)傳到了Photo
模塊,imageURL
和 caption
。imageURL
屬性被用做React元素中的src
。而caption
屬性則以純文本的方式在React中的span元素使用。
值得一提的是,模塊永遠不該該去改變屬性的的值,它們是不可變的。若是一個模塊有一個可變的數據,那應該應用使用狀態對象(state object)。
狀態對象是一個模塊的內部對象。它會持有可變的數據。
var Photo = React.createClass({ toggleLiked: function() { this.setState({ liked: !this.state.liked }); }, getInitialState: function() { return { liked: false } }, render: function() { var buttonClass = this.state.liked ? 'active' : ''; return ( <div className='photo'> <img src={this.props.src} /> <div className='bar'> <button onClick={this.toggleLiked} className={buttonClass}> ♥ </button> <span>{this.props.caption}</span> </div> </div> ) } }); React.render(<Photo src='http://owenyang0.github.io/img/background.jpg' caption='Headset'/>, document.body);
在模塊中引入狀態,會增長一點點的複雜度。
在這模塊中,有一個新的函數getInitialState
。當模塊初始化的時候,React會調用這個函數。而返回的對象則做爲React的初始化狀態(看函數名就知道)。
還有一個新的函數叫toggleLiked
。這個函數調用了模塊上的setState方法,能夠改變狀態liked
的值。
經過模塊的render函數,變量buttonClass
被賦值成了'active'或者空,這都依賴於liked
狀態。
buttonClass
是React按鈕元素的class名字。按鈕還擁有一個onClick
的事件回調,指向toggleLiked
函數。
當模塊渲染成瀏覽器DOM的時候,究竟發生全過程:
toggleLiked
liked
的狀態被改變在這個場景中,React會改變button上的類名。
組合的意思是說,將小的分散的模塊組成一個大的總體。好比Photo
模塊能夠在PhotoGallery
中使用:
var Photo = React.createClass({ toggleLiked: function() { this.setState({ liked: !this.state.liked }); }, getInitialState: function() { return { liked: false } }, render: function() { var buttonClass = this.state.liked ? 'active' : ''; return ( <div className='photo'> <img src={this.props.src} /> <div className='bar'> <button onClick={this.toggleLiked} className={buttonClass}> ♥ </button> <span>{this.props.caption}</span> </div> </div> ) } }); var PhotoGallery = React.createClass({ getDataFromServer: function() { return [{ url: 'http://owenyang0.github.io/img/background.jpg', caption: 'Headset' }, { url: 'http://owenyang0.github.io/images/mocha.png', caption: 'Mocha' }, { url: 'http://owenyang0.github.io/images/catalog.png', caption: 'Catelog' }]; }, render: function() { var data = this.getDataFromServer(); var photos = data.map(function(photo) { return <Photo src={photo.url} caption={photo.caption} /> }); return ( <div className='photo-gallery'> {photos} </div> ) } }); React.render(<PhotoGallery />, document.body);
這個Photo
模塊完徹底全和上面的同樣。但新的PhotoGallery
模塊會生成Photo
模塊。該場景中,僞造了返回包含三個對象的數組的數據,每個對象都返回一個url和其標題。經過循環,生成了三個Photo
的模塊,將最終的返回值插入到render
函數之中。
用React來構建你的用戶界面,我想這也差很少了。React的文檔手冊,包含了全部的細節。強烈推薦你們去讀一下。
一樣的,該文也沒有涉及你本地環境安裝的細節。文檔都會有的。