React
組件開發入門
Introduction
本文組成:
- Ryan Clark文章Getting started with React的翻譯。
- 博主的實踐心得。
React由Facebook的程序員創建,是一個非常強大的javascript類庫。
一個很大的賣點是virtual DOM機制,在DOM操作的性能上有較大的優勢。
React社區常常介紹它為MVC架構中的“V”,雖說如此,如果將React與Flux(以后將會介紹)結合,我們就可以輕松實現M與V的同步。
在本文中,將會用到博主前兩天介紹的webpack。以下是博文鏈接:
webpack 學習筆記 01 使用webpack的原因
webpack 學習筆記 02 快速入門
Components
通過React,我們可以專注於可復用的組件開發,比如:一個下拉導航欄組件,一個功能齊全的數據表格。React中,像CommonJs標准中一樣,React的組件與組件也能良好隔離,可以隨意的在組件內部增加功能。
所有的React組件都需要實現一個函數: render,我們可以通過它,返回HTML或者調用其它的組件。正是這個基本的功能,給React帶來了無限可能。
JSX
如果你曾經看過React相關的信息,那可能會對一個名詞印象比較深刻:JSX。JSX使js無需""的包裝,編寫各類html tag。使得我們可以更快速的開發React組件(考慮到多行問題,在js中寫HTML原本還是很麻煩的)。
我們可以借助一個js庫,在瀏覽器中將JSX轉換為js,但這不是推薦的做法,本文介紹了如何通過webpack在本地實現JSX到js的轉換,使得瀏覽器不用解決這一問題。
Using JSX
render扮演着"ViewModel"的角色,在我們返回HTML信息前,將Model注入View,並加入各類js邏輯。
現在,我們新建一個目錄,建立以下文件
index.html
entry.js
webpack.config.js
借助npm與bower我們可以快速下載依賴項
npm init
npm install babel-loader --save bower install react bower init
以下是index.html的內容,借助webpack,我們可以不用再修改它,就完成本示例了。
<html> <head> <meta charset="utf-8"> <title>react demo</title> </head> <body> <script type="text/javascript" src="bundle.js" charset="utf-8"></script> </body> </html>
以下是webpack配置內容
module.exports = { entry: "./entry.js", output:{ path: __dirname, filename: "bundle.js" }, module: { loaders: [ { test: /\.js?$/, exclude: /(node_modules|bower_components)/, loader: 'babel' } ]} }
配置做好了,讓我們開始第一個JSX。
var React = require("./bower_components/react/react.js"); var Widget = React.createClass({ render:function(){ return( <div> <h1>React with webpack</h1> </div>); } }); React.render(<Widget />, document.body);
運行指令
webpack -w
可以看到如下結果:
Using variables for attributes
如前文所說,React組件里可以加入任意的js邏輯,我們可以把剛才的JSX改成這樣:
var Widget = React.createClass({ render:function(){ var text = "React with webpack"; return( <div> <h1>{text}</h1> </div>); } });
Basics of a component
組件可以維護自己作用域下的各類狀態值。使我們得以復用各類組件。
當我們通過向組件的attributes傳值時,他們會作為properties而引用。這句話可能不好理解,我們看下代碼:
var Widget = React.createClass({ render:function(){ var text = ""; return( <div> <h1>{this.props.displayText}</h1> </div>); } }); React.render(<Widget displayText="React with webpack"/>, document.body);
State
properties適合用在一次渲染,不需要改變的組件場景。在狀態需要動態改變的場合,我們會用到state。通過this.setState 函數以改變狀態值,之后,組件會重新渲染(借助virtual DOM機制,這一部分還是蠻快的)。 以下是Demo
var Widget = React.createClass({
getInitialState: function(){
return{
number: 0 }; }, increment: function(){ this.setState({ number: this.state.number + 1 }); }, render: function(){ return( <div> <h1>{this.state.number}</h1> <button onClick={this.increment}>Inc</button> </div>); } });
顯示的數字將伴隨按鈕點擊上升。
The component lifecycle
所有的組件都是有生命周期的,這無疑為我們開發提供了很大的便利。比如剛才例子中的getInitialState,只會在控件裝載(mount)后,調用一次。當然還有其它的生命周期函數:componentWillMount在組件即將裝載前調用,可以把Ajax放這。componentDidMount在組件已經被渲染出了DOM后調用,這時,我們可以借助this.getDOMNode取到跟節點,做一些后續工作。componentWillUnmount組件被移除時,相關資源的清理工作,就得在這里(如移除EventHandler,若EventHandler操作了不存在的組件,error自然就被拋出)。
Component Methods
通過getDefaultProps,我們可以為properties提供默認值,即當properties沒有通過attributes傳入,這些默認值會派上用場。
var Widget = React.createClass({ getDefaultProps: function(){ return{ number: 10 }; }, render: function(){ return( <div> <h1>{this.props.number}</h1> </div>); } }); React.render(<Widget/>, document.body);
React並不提倡提供過多的模版功能,它提倡的是回歸原始,比如:當我們需要用到repeater。我們可以這樣:
var Widget = React.createClass({ render: function(){ var data =[1,2,3,4]; //請假設這是有用數據 var content = data.map(function(item){ return (<h2>{item}</h2>) }); return( <div> <h1>{content}</h1> </div>); } });

