React JS快速開始手冊
怎樣用React JS構建一個使用者介面?本文將快速地給你一個React JS的概覽。程式碼,請君移步react-starter
概念
React只有很少的API,這使得它很容易去學習與理解。當然,使用它也是相當有意思的。但是,簡約卻並不簡單。在我們開始之前,有一些概念是需要去理解的。
React元素(React elements)
React元素是用於呈現HTML結構的JavaScript物件。它們不會存在於瀏覽器中,只是用於描述瀏覽器中的元素,比如h1
, div
或者 section
等等。
模組(Components)
模組是開發者建立的React元素。它們通過比使用者介面的範圍要大,因為它們同時包含了其結構與功能。想像一下導航欄,點贊按鈕,圖片上傳這些模組的概念。
JSX
JSX是一種用於建立React元素和模組的技術,或者說是規範、語言。比如 <h1>Hello</h1>
便是一個用JSX所寫的React元素。同樣的React元素,可以用原生的JavaScript實現,即 React.DOM.h1(null, 'Hello');
。相比原生的JavaScript,JSX更加簡潔。會讓你花更少的精力去讀和寫程式碼,在上線的時候將其轉換成原生的JavaScript即可。
虛擬DOM(Virtual DOM)
虛擬DOM是一個JavaScript的樹形結構,包含了React元素和模組。React通過渲染虛擬DOM到瀏覽器,使得使用者介面得以顯示。React也會觀察虛擬DOM的變化,根據虛擬DOM自動地改變瀏覽器DOM元素。
瞭解了這些概念之後,我們就可以暢快地敲React程式碼了。這裡將會建立一系列的使用者介面,每一個介面都將提前新增一層功能層。我們會做一個類似instagram的應用 - 當然,這個很粗糙。
渲染(Rendering)
業務的第一步是渲染一個虛擬的元素(React元素或者模組都可以)。由於每一個虛擬元素都存在於記憶體之中,所以我們必須顯式地告訴React,將其渲染到瀏覽器的DOM之中。
React.render(<img src='http://owenyang0.github.io/img/background.jpg' />, document.body);
render
函式接受兩個引數,一個是虛擬元素,一個是真實的DOM節點。React就是獲取到虛擬元素之後,將其插入到所給的節點之中。此時,在瀏覽器中便可以看到照片了。
模組(Components)
模組是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影象元素做更多的事情,但這卻更加有利於在功能和結構上進行擴充套件。
屬性(Props)
屬性可以認為是模組的一些配置選項。它們以引數(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)。
狀態(State)
狀態物件是一個模組的內部物件。它會持有可變的資料。
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將模組再次渲染成虛擬DOM
- 新的虛擬DOM與舊的虛擬DOM相比較
- React將改變的部分隔離,然後更新到瀏覽器DOM
在這個場景中,React會改變button上的類名。
組合(Composition)
組合的意思是說,將小的分散的模組組成一個大的整體。比如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的文件手冊,包含了所有的細節。強烈推薦大家去讀一下。
同樣的,該文也沒有涉及你本地環境安裝的細節。文件都會有的。