在公司用React做項(xiàng)目已經(jīng)有一年多了侧纯,剛開(kāi)始接觸它的時(shí)候嘉栓,給我的第一感覺(jué)就是很有顛覆性,一言不合就往JS里面插入Html代碼捐祠。在MVC或者M(jìn)VVM的框架里碱鳞,我們宣揚(yáng)的是視圖V和模型M的分離,就是你負(fù)責(zé)扮靚踱蛀,我負(fù)責(zé)賺錢窿给。而React更多的是宣揚(yáng)組件化思想,各位看官請(qǐng)看下圖率拒。
那React到底有哪些好處呢崩泡?為了方便看官查閱,我在此羅列了出來(lái)猬膨。
- “輕”角撞;react是很輕量的框架
- 速度快,效率高勃痴;真正Dom其實(shí)是很巨大的谒所,直接操作Dom很耗性能。React引入virtual dom概念沛申,它不直接操作Dom而是將Dom結(jié)構(gòu)存儲(chǔ)在內(nèi)存中劣领,然后通過(guò)render中返回的內(nèi)容做一個(gè)Dom Diff的比較,再將變化反映到Dom做局部更新铁材。
- 組件化思想剖踊;利用React可以輕松構(gòu)建所需要的組件,并且各組件之間可輕易的組合衫贬,使得代碼重用及各模塊之間的測(cè)試變得更加簡(jiǎn)單德澈。
- 單向式響應(yīng)數(shù)據(jù)流;React實(shí)現(xiàn)了單向式相應(yīng)數(shù)據(jù)流固惯,使得數(shù)據(jù)交互變得非常簡(jiǎn)易清晰梆造,減少了許多重復(fù)代碼,比傳統(tǒng)的數(shù)據(jù)綁定簡(jiǎn)單。
那React到底是怎么一回事呢镇辉,我們現(xiàn)在來(lái)揭開(kāi)它的神秘面紗屡穗,例行慣例先來(lái)一段Hello World。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );
</script>
</body>
</html>
以上的頁(yè)面在瀏覽器打開(kāi)就可以清晰的看到Hello, world!了忽肛。以上代碼的最后一個(gè)<script>片段要特別注意村砂,它的Type是text/babel,用此標(biāo)簽的作用是讓babel識(shí)別出并最終將jsx語(yǔ)句轉(zhuǎn)換為瀏覽器可識(shí)別可運(yùn)行的js語(yǔ)句屹逛。
上述代碼我們引用了三個(gè)庫(kù)
react.js:React的核心庫(kù)
react-dom.js: 提供與DOM的相關(guān)的功能
browser.min.js: 解析jsx語(yǔ)法础废,將jsx語(yǔ)法轉(zhuǎn)換為JavaScript語(yǔ)法,實(shí)際上這一部很消耗時(shí)間應(yīng)該放在服務(wù)器完成
當(dāng)然你也可以把ReactJs的代碼提取出來(lái)罕模,為了讓它看起來(lái)有組件的樣子评腺,我們改造成如下樣子。
var HelloWorld = React.createClass({
render: function() {
return (
<h1>Hello, world!</h1>
);
}
});
ReactDOM.render(<HelloWorld/>, document.getElementById("example"));
Html頁(yè)面只需要引用它就可以了
<script type="text/babel" src="src/helloworld.js"></script>
需要注意的是淑掌,頁(yè)面在某些瀏覽器打開(kāi)可能會(huì)報(bào)錯(cuò)無(wú)法加載該文件例如谷歌chrome蒿讥,原因是它不是http請(qǐng)求,如果放在服務(wù)器是完全沒(méi)有問(wèn)題的抛腕。但我們沒(méi)有服務(wù)器想在本地看看怎么辦芋绸,別急,還是有辦法的担敌。Mac可以先退出瀏覽器再用以下命令打開(kāi)谷歌chrome侥钳。
open -a Google\ Chrome --args --disable-web-security --allow-file-access-from-files --user-data-dir=""
Windows的可以右擊谷歌瀏覽器快捷方式,打開(kāi)屬性在目標(biāo)位置后加上如下參數(shù)
--args --disable-web-security --allow-file-access-from-files --user-data-dir=""
繼續(xù)說(shuō)上面的代碼柄错,我們可以看到我們使用了<HelloWorld/>給id為example的元素渲染了內(nèi)容Hello, world!而此時(shí)此刻我們所創(chuàng)建的這個(gè)React對(duì)象就是個(gè)簡(jiǎn)單的組件了舷夺。這里有一點(diǎn)切記組件名字開(kāi)頭一定要大寫。
現(xiàn)在假如我不想組件返回一個(gè)Hello售貌,world給我我想說(shuō)點(diǎn)別的给猾,比如說(shuō)洋氣的中文“你好世界”要怎么做呢。這時(shí)候我們可以用React的props颂跨。
var HelloWorld = React.createClass({
render: function() {
return (
<h1>{this.props.words}</h1>
);
}
});
ReactDOM.render(<HelloWorld words="你好世界"/>, document.getElementById("example"));
props可用于父組件向子組件傳值敢伸,這將是組件的一個(gè)初始值,一旦設(shè)置之后將不能修改恒削。
你可能想父組件在沒(méi)有傳值給子組件時(shí)池颈,子組件可以有默認(rèn)的值可以用,這時(shí)候這個(gè)方法getDefaultProps就派上用場(chǎng)了钓丰。該方法是默認(rèn)給props的各屬性設(shè)置相應(yīng)的值躯砰。
var HelloWorld = React.createClass({
getDefaultProps: function(){
return {
words: "你好世界"
};
},
render: function() {
return (
<h1>{this.props.words}</h1>
);
}
});
ReactDOM.render(<HelloWorld/>, document.getElementById("example"));
組件肯定避免不了要與用戶互動(dòng),當(dāng)有數(shù)據(jù)更新的時(shí)候携丁,我們要怎么把新數(shù)據(jù)渲染到界面上呢琢歇。這里我們?nèi)杂蒙弦粋€(gè)栗子來(lái)闡述這個(gè)問(wèn)題,這時(shí)候我們會(huì)用到state。
var HelloWorld = React.createClass({
getInitialState: function(){
return {
words: "Hello, world!"
};
},
sayChinese: function(){
this.setState({words: "你好,世界!"});
},
render: function() {
return (
<div>
<h1>{this.state.words}</h1>
<button onClick={this.sayChinese}>Say Chinese!</button>
</div>
);
}
});
ReactDOM.render(<HelloWorld/>, document.getElementById("example"));
同props一樣李茫,state也可以通過(guò)getInitialState設(shè)置初始值揭保,當(dāng)用戶點(diǎn)擊組件,調(diào)用了方法setState修改了狀態(tài)值魄宏,導(dǎo)致組件的狀態(tài)變化秸侣,每次修改完成后都會(huì)自動(dòng)調(diào)用render方法重新渲染組件,從這里也可以看出單向數(shù)據(jù)流的特性宠互。
看起來(lái)好像組件都可以調(diào)用props的值或者state里的屬性值來(lái)展示渲染數(shù)據(jù)味榛,但其實(shí)這兩者是有根本區(qū)別的。
props一旦定義就不能改變名秀,state可以隨時(shí)改變
props主要組件用于初始化,state用于與用戶交互和組件更新