先講故事:周一同事給我看了新頁(yè)面的原型烘挫,有大量新增的表單诀艰。也就是說(shuō),會(huì)有相當(dāng)數(shù)量的dom操作饮六。眾所周知其垄,用js去生成dom性能是相當(dāng)差的。怎么來(lái)實(shí)現(xiàn)需求的同時(shí)提升性能呢卤橄? 找小強(qiáng)討論--用React绿满!
漫談
現(xiàn)在最紅的幾個(gè)前端框架是什么?AngularJs窟扑?Backboon喇颁?ReactJs?對(duì)嚎货,他們都算是當(dāng)紅炸子雞无牵。都是用來(lái)實(shí)現(xiàn)模塊化、自動(dòng)化雙向數(shù)據(jù)綁定厂抖、語(yǔ)義化標(biāo)簽茎毁。
于是,為什么我選React忱辅?Backboon第一個(gè)被排除七蜘,對(duì)他是這個(gè)領(lǐng)域的鼻祖。然并卵墙懂,他老了橡卤,且很久沒(méi)跟新了,最根本的內(nèi)存泄漏問(wèn)題始終沒(méi)有解決损搬。
AngularJS碧库,唔嗷~ 很抱歉我沒(méi)用過(guò)這貨柜与,盡管它擴(kuò)展性非常強(qiáng),但是他的學(xué)習(xí)曲線太陡峭了嵌灰,而且這次我們僅僅是為了解決動(dòng)態(tài)dom性能的問(wèn)題弄匕,AngularJS太龐大了。我們并不是說(shuō)React的功能不強(qiáng)大沽瞭,要知道React是從最早的UI引擎變成了一整套前后端通吃的 Web App 解決方案迁匠。終極目標(biāo)是用web app的方式去寫(xiě)native app~ 然后我們只要寫(xiě)一次ui,就同時(shí)能在服務(wù)區(qū) 瀏覽器和手機(jī)上看啦~
回歸主題驹溃,React生成dom為毛性能那么好城丧?根據(jù) React 的設(shè)計(jì),所有的 DOM 變動(dòng)豌鹤,都先在虛擬 DOM 上發(fā)生亡哄,然后再將實(shí)際發(fā)生變動(dòng)的部分,反映在真實(shí) DOM上布疙,這種算法叫做 DOM diff 蚊惯,它可以極大提高網(wǎng)頁(yè)的性能表現(xiàn)。有興趣可以了解下拐辽,當(dāng)然你也別來(lái)問(wèn)我拣挪,我是拾人牙慧,算法什么的我完全不懂俱诸。
搞起
明確下我們只搞瀏覽器端菠劝!好了 搞~
標(biāo)準(zhǔn)代碼格式
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/JSXTransformer.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx">
xx帥帥嗒
</script>
</body>
</html>
script 標(biāo)簽的 type 屬性為 text/jsx 。這是因?yàn)?React 獨(dú)有的 JSX 語(yǔ)法睁搭,跟 JavaScript 不兼容赶诊。凡是使用 JSX 的地方,都要加上 type="text/jsx"
- React 提供兩個(gè)庫(kù): react.js 和 JSXTransformer.js 园骆,它們必須首先加載舔痪。其中,JSXTransformer.js 的作用是將 JSX 語(yǔ)法轉(zhuǎn)為 JavaScript 語(yǔ)法锌唾。這一步很消耗時(shí)間锄码,實(shí)際上線的時(shí)候,應(yīng)該將它放到服務(wù)器完成晌涕。這個(gè)我倒最后再講滋捶。下面我們就寫(xiě)個(gè)demo
- ```
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/JSXTransformer.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx">
React.render(
<h1>Hello, Rex!</h1>,
document.getElementById('example')
);
</script>
</body>
</html>
啊發(fā)現(xiàn)有什么特別~ 跟傳統(tǒng)js相比jsx語(yǔ)法允許直接寫(xiě)html標(biāo)簽,不需要引號(hào)~
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/JSXTransformer.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx">
var names = ['Rex', 'xx', 'Sxx'];
React.render(
<div>
{
names.map(function (name) {
return <div>Hello, {name}!</div>
})
}
</div>,
document.getElementById('example')
);
</script>
</body>
</html>
這個(gè)demo說(shuō)明把jsx語(yǔ)法解釋的更清楚余黎,遇到<開(kāi)頭的html標(biāo)簽就用html來(lái)解析重窟,遇到{開(kāi)頭的用js規(guī)則解析。
var arr = [
<h1>Hello world!</h1>,
<h2>Rex is superman</h2>,
];
React.render(
<div>{arr}</div>,
document.getElementById('example')
);
如果數(shù)組里的對(duì)象像這個(gè)demo一樣是html結(jié)構(gòu)的話惧财,將會(huì)直接被輸出
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 (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});
React.render(
<LikeButton />,
document.getElementById('example')
);
getInitialState 方法用于定義初始狀態(tài)巡扇,也就是一個(gè)對(duì)象扭仁,這個(gè)對(duì)象可以通過(guò) this.state 屬性讀取。當(dāng)用戶點(diǎn)擊組件厅翔,導(dǎo)致?tīng)顟B(tài)變化乖坠,this.setState 方法就修改狀態(tài)值,每次修改以后知给,自動(dòng)調(diào)用 this.render 方法瓤帚,再次渲染組件
警告描姚!
- 昨天回去嘗試寫(xiě)demo涩赢,發(fā)現(xiàn)出問(wèn)題了,搞了好久~ 問(wèn)題出在0.13版更新之后提供了對(duì)ES6的支持轩勘。并且取消了了函數(shù)自動(dòng)綁定筒扒。用新版React去跑我demo的同學(xué),xx在這里給你道歉了~舉例:
<button onClick={this.handleSubmit}>Submit</button>
需要改寫(xiě)成
<button onClick={this.handleSubmit.bind(this)}>Submit</button>
未完待續(xù)