React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架,都不滿(mǎn)意,就決定自己寫(xiě)一套,用來(lái)架設(shè) Instagram 的網(wǎng)站。做出來(lái)以后,發(fā)現(xiàn)這套東西很好用,就在2013年5月開(kāi)源了。由于 React 的設(shè)計(jì)思想極其獨(dú)特,屬于革命性創(chuàng)新,性能出眾,代碼邏輯卻非常簡(jiǎn)單。所以,越來(lái)越多的人開(kāi)始關(guān)注和使用,認(rèn)為它可能是將來(lái) Web 開(kāi)發(fā)的主流工具。
創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)服務(wù)商,為中小企業(yè)提供成都網(wǎng)站制作、網(wǎng)站建設(shè)服務(wù),網(wǎng)站設(shè)計(jì),網(wǎng)站托管維護(hù)等一站式綜合服務(wù)型公司,專(zhuān)業(yè)打造企業(yè)形象網(wǎng)站,讓您在眾多競(jìng)爭(zhēng)對(duì)手中脫穎而出創(chuàng)新互聯(lián)公司。
ReactJS官網(wǎng)地址:http://facebook.github.io/react/
Github地址:https://github.com/facebook/react
React認(rèn)為一個(gè)組件應(yīng)該具有如下特征:
(1)可組合(Composeable):一個(gè)組件易于和其它組件一起使用,或者嵌套在另一個(gè)組件內(nèi)部。如果一個(gè)組件內(nèi)部創(chuàng)建了另一個(gè)組件,那么說(shuō)父組件擁有(own)它創(chuàng)建的子組件,通過(guò)這個(gè)特性,一個(gè)復(fù)雜的UI可以拆分成多個(gè)簡(jiǎn)單的UI組件;
(2)可重用(Reusable):每個(gè)組件都是具有獨(dú)立功能的,它可以被使用在多個(gè)UI場(chǎng)景;
(3)可維護(hù)(Maintainable):每個(gè)小的組件僅僅包含自身的邏輯,更容易被理解和維護(hù);
我們新建一個(gè)html文件,引用react.js和JSXTransformer.js這兩個(gè)js文件。html模板如下(js路徑改成自己的):
script的type是text/babel,這是因?yàn)?React 獨(dú)有的 JSX 語(yǔ)法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel" 。
其次,上面代碼一共用了三個(gè)庫(kù): react.js 、react-dom.js 和 Browser.js ,它們必須首先加載。其中,react.js 是 React 的核心庫(kù),react-dom.js 是提供與 DOM 相關(guān)的功能,Browser.js 的作用是將 JSX 語(yǔ)法轉(zhuǎn)為 JavaScript 語(yǔ)法,這一步很消耗時(shí)間,實(shí)際上線的時(shí)候,應(yīng)該將它放到服務(wù)器完成。
下面開(kāi)始看react該怎么寫(xiě),還是傳統(tǒng)的老規(guī)矩 hello word:
在上例的body中,有一個(gè)div,id是example, 然后由react的渲染器把h2標(biāo)簽渲染到該div中。
ReactDOM.render(DOM節(jié)點(diǎn),被插入的父節(jié)點(diǎn));
這一句代碼是最常用也是非常必要的一句。 這句中有個(gè)很重要的地方就是html語(yǔ)法和js語(yǔ)法的混寫(xiě),這是jsx語(yǔ)法的特點(diǎn),在jsx語(yǔ)法里,遇到 尖括號(hào)就按照html來(lái)解析,遇到花括號(hào)就按照js語(yǔ)法去解析。下面這個(gè)例子更能說(shuō)明jsx語(yǔ)法的寫(xiě)法:
var list = ["word","man","boy"]; ReactDOM.render({ list.map(function (name){ return,document.getElementById('example'));hello {name}}) }
最終的結(jié)果是:
hello word
hello man
hello boy
這里有一點(diǎn)需要說(shuō)明的是 ReactDOM.render 渲染器的第一個(gè)參數(shù)里,有且只能有一個(gè)頂級(jí)節(jié)點(diǎn),不能有多個(gè)并列,否則會(huì)報(bào)錯(cuò)。JSX 允許直接在模板插入 JavaScript 變量。如果這個(gè)變量是一個(gè)數(shù)組,則會(huì)展開(kāi)這個(gè)數(shù)組的所有成員。
var list = [word
,man
,boy
]; ReactDOM.render({list},document.getElementById('example'));
最終結(jié)果是:
React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標(biāo)簽一樣,在網(wǎng)頁(yè)中插入這個(gè)組件。React.createClass 方法就用于生成一個(gè)組件類(lèi):
var HelloWord = React.createClass({ render:function(){ returnhello {this.props.name}
} }); ReactDOM.render(,document.getElementById('example'));
最終結(jié)果是:
hello 喵星人
上例中用React.createClass創(chuàng)建了一個(gè)組件類(lèi)HelloWord,這里有一點(diǎn)需要注意:組件類(lèi)名字的首字母必須是大寫(xiě)的,否則會(huì)報(bào)錯(cuò)。React.createClass接收一個(gè)對(duì)象,對(duì)象中必須有render屬性,render屬性的值一般都是寫(xiě)成一個(gè)函數(shù),然后返回一個(gè)DOM對(duì)象,別忘了上面說(shuō)的,這個(gè)DOM對(duì)象有且只能有一個(gè)頂級(jí)節(jié)點(diǎn),否則會(huì)報(bào)錯(cuò)。
我們?cè)谏厦娴拇a的return 里會(huì)看到有這么一段:this.props.name,然后在ReactDom.render中的第一個(gè)參數(shù)里會(huì)看到標(biāo)簽有一個(gè)屬性name="喵星人",這里需要記住的一點(diǎn)是name="喵星人"看上去就像在對(duì)函數(shù)傳參數(shù),而this.props.name就是對(duì)參數(shù)的接收。
添加組件屬性,有一個(gè)地方需要注意,就是 class 屬性需要寫(xiě)成 className ,for 屬性需要寫(xiě)成 htmlFor ,這是因?yàn)?nbsp;class 和 for 是 JavaScript 的保留字。
this.props 對(duì)象的屬性與組件的屬性一一對(duì)應(yīng),但是有一個(gè)例外,就是 this.props.children 屬性。它表示組件的所有子節(jié)點(diǎn)。
var NotesList = React.createClass({ render: function() { return ({ this.props.children.map(function (child) { return
); }});ReactDOM.render(- {child}
; }) }hello world , document.getElementById('example'));main
最終運(yùn)行結(jié)果:
hello
world
3. main
2 和3之間的換行是因?yàn)閜標(biāo)簽會(huì)自帶一個(gè)換行,li標(biāo)簽也會(huì)有一個(gè)換行,所以中間就有了一個(gè)空白行.
組件免不了要與用戶(hù)互動(dòng),React 的一大創(chuàng)新,就是將組件看成是一個(gè)狀態(tài)機(jī),一開(kāi)始有一個(gè)初始狀態(tài),然后用戶(hù)互動(dòng),導(dǎo)致?tīng)顟B(tài)變化,從而觸發(fā)重新渲染 UI
var LikeButton = React.createClass({ getInitialState: function() { return {liked: false}; }, handleClick: function(event) { this.setState({liked: !this.state.liked}); }, render: function() { var text = this.state.liked ? 'like' : 'haven\'t liked'; return (You {text} this. Click to toggle.
); }});ReactDOM.render(, document.getElementById('example'));
最終結(jié)果:
You haven't liked this. Click to toggle.
當(dāng)在文字上點(diǎn)擊時(shí)會(huì)變成:
You like this. Click to toggle.
然后一直點(diǎn)擊就會(huì)在兩句英文之間來(lái)回切換。
這里需要注意的是 getInitialState 是React默認(rèn)的屬性,需要返回一個(gè)對(duì)象,可以是NULL或者其他,表示初始狀態(tài),返回的對(duì)象中可以不止有一個(gè)屬性,修改這些狀態(tài)可以使用react提供的方法this.setState(對(duì)象), 這里的對(duì)象可以只修改初始狀態(tài)中的某一個(gè)屬性,也可以同時(shí)修改多個(gè)。當(dāng)任何一個(gè)狀態(tài)改變的時(shí)候react就會(huì)重新調(diào)用 render屬性所指向的函數(shù),也就意味著會(huì)重新渲染該組件。
組件的生命周期分成三個(gè)狀態(tài):
Mounting:已插入真實(shí) DOM
Updating:正在被重新渲染
Unmounting:已移出真實(shí) DOM
React 為每個(gè)狀態(tài)都提供了兩種處理函數(shù),will 函數(shù)在進(jìn)入狀態(tài)之前調(diào)用,did 函數(shù)在進(jìn)入狀態(tài)之后調(diào)用,三種狀態(tài)共計(jì)五種處理函數(shù)。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
此外,React 還提供兩種特殊狀態(tài)的處理函數(shù)。
componentWillReceiveProps(object nextProps):已加載組件收到新的參數(shù)時(shí)調(diào)用
shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時(shí)調(diào)用
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 (Hello {this.props.name}); }});ReactDOM.render(, document.body);
上面代碼在hello組件加載以后,通過(guò) componentDidMount 方法設(shè)置一個(gè)定時(shí)器,每隔100毫秒,就重新設(shè)置組件的透明度,從而引發(fā)重新渲染。這里需要注意的地方是在setInterval的第一個(gè)參數(shù)也就是計(jì)時(shí)器觸發(fā)函數(shù)后使用了bind(this),計(jì)時(shí)器函數(shù)中不能直接使用this來(lái)獲取react的狀態(tài)或?qū)傩?,需要綁定this。
小結(jié):
react提供的屬性:
getInitialState 設(shè)置默認(rèn)狀態(tài)
setState 修改狀態(tài)
render 返回組件
componentWillMount() 插入真實(shí)DOM之前調(diào)用
componentDidMount() 插入真實(shí)DOM之后調(diào)用
componentWillUpdate(object nextProps, object nextState) 重新渲染之前調(diào)用
componentDidUpdate(object prevProps, object prevState) 重新渲染之后調(diào)用
componentWillUnmount() 移出真實(shí)DOM之前調(diào)用
propTypes 驗(yàn)證組件實(shí)例的屬性是否符合要求
getDefaultProps 設(shè)置組件屬性的默認(rèn)值。
最后兩個(gè)屬性本文中沒(méi)有介紹,詳細(xì)介紹請(qǐng)參閱http://www.ruanyifeng.com/blog/2015/03/react.html