寫在前面
React入門學(xué)習(xí)筆記。
教程可參考:
React 教程 | 菜鳥(niǎo)教程
阮一峰的網(wǎng)絡(luò)日志 > React 入門實(shí)例教程
自己用React寫了一個(gè)to-do-list的小demo:
react-todolist
歡迎評(píng)論指出問(wèn)題败砂,一起學(xué)習(xí)昌犹。
01 React簡(jiǎn)介
React 是一個(gè)用于構(gòu)建用戶界面的 JAVASCRIPT 庫(kù)。
React主要用于構(gòu)建UI鸿竖,很多人認(rèn)為 React 是 MVC 中的 V(視圖)铸敏。
React 起源于 Facebook 的內(nèi)部項(xiàng)目杈笔,用來(lái)架設(shè) Instagram 的網(wǎng)站,并于 2013 年 5 月開(kāi)源球榆。
React 擁有較高的性能禁筏,代碼邏輯非常簡(jiǎn)單篱昔,越來(lái)越多的人已開(kāi)始關(guān)注和使用它。
02 React特點(diǎn)
聲明式設(shè)計(jì) ?React采用聲明范式舀射,可以輕松描述應(yīng)用脆烟。
高效 ?React通過(guò)對(duì)DOM的模擬房待,最大限度地減少與DOM的交互。
靈活 ?React可以與已知的庫(kù)或框架很好地配合拜鹤。
JSX ? JSX 是 JavaScript 語(yǔ)法的擴(kuò)展敏簿。React 開(kāi)發(fā)不一定使用 JSX ,但我們建議使用它温数。
組件 ? 通過(guò) React 構(gòu)建組件蜻势,使得代碼更加容易得到復(fù)用握玛,能夠很好的應(yīng)用在大項(xiàng)目的開(kāi)發(fā)中。
單向響應(yīng)的數(shù)據(jù)流 ? React 實(shí)現(xiàn)了單向響應(yīng)的數(shù)據(jù)流冕屯,從而減少了重復(fù)代碼愕撰,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡(jiǎn)單醋寝。
03 React安裝與使用
實(shí)例中我們引入了三個(gè)庫(kù): react.min.js 音羞、react-dom.min.js 和 babel.min.js:
react.min.js - React 的核心庫(kù)
react-dom.min.js - 提供與 DOM 相關(guān)的功能
babel.min.js - Babel 可以將 ES6 代碼轉(zhuǎn)為 ES5 代碼仓犬,這樣我們就能在目前不支持 ES6 瀏覽器上執(zhí)行 React 代碼搀继。Babel 內(nèi)嵌了對(duì) JSX 的支持。通過(guò)將 Babel 和 babel-sublime 包(package)一同使用可以讓源碼的語(yǔ)法渲染上升到一個(gè)全新的水平财边。
也可以用npm來(lái)安裝并創(chuàng)建項(xiàng)目:
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start
04 React JSX
簡(jiǎn)介
React 使用 JSX 來(lái)替代常規(guī)的 JavaScript酣难。
JSX 是一個(gè)看起來(lái)很像 XML 的 JavaScript 語(yǔ)法擴(kuò)展黑滴。
我們不需要一定使用 JSX袁辈,但它有以下優(yōu)點(diǎn):
- JSX 執(zhí)行更快,因?yàn)樗诰幾g為 JavaScript 代碼后進(jìn)行了優(yōu)化尾膊。
- 它是類型安全的,在編譯過(guò)程中就能發(fā)現(xiàn)錯(cuò)誤济舆。
- 使用 JSX 編寫模板更加簡(jiǎn)單快速莺债。
使用JSX
JSX 看起來(lái)類似 HTML 齐邦,我們可以看下實(shí)例:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
我們可以在以上代碼中嵌套多個(gè) HTML 標(biāo)簽,需要使用一個(gè) div 元素包裹它我纪,實(shí)例中的 p 元素添加了自定義屬性 data-myattribute浅悉,添加自定義屬性需要使用 data- 前綴券犁。
JSX可以放在一個(gè)獨(dú)立文件中粘衬,在HTML文件中引入JSX時(shí)需要將type="text/babel"。
在JSX中使用javascript表達(dá)式
我們可以在 JSX 中使用 JavaScript 表達(dá)式勘伺。表達(dá)式寫在花括號(hào) {} 中褂删。實(shí)例如下:
ReactDOM.render(
<div>
<h1>{1+1}</h1>
</div>
document.getElementById('example')
);
不能使用if語(yǔ)句飞醉,可以用三元表達(dá)式代替。
React內(nèi)聯(lián)樣式
React推薦使用內(nèi)聯(lián)樣式笤妙,使用駝峰寫法冒掌,自動(dòng)補(bǔ)全px。
var myStyle = {
fontSize: 100,
color: '#FF0000'
};
ReactDOM.render(
<h1 style = {myStyle}>菜鳥(niǎo)教程</h1>,
document.getElementById('example')
);
其他
標(biāo)簽內(nèi)部的注釋需要花括號(hào)蹲盘。
允許在模板中插入數(shù)組股毫。
React 的 JSX 使用大、小寫的約定來(lái)區(qū)分本地組件的類和 HTML 標(biāo)簽召衔。
05 React組件
注意铃诬,原生 HTML 元素名以小寫字母開(kāi)頭,而自定義的 React 類名以大寫字母開(kāi)頭趣席,比如 HelloMessage 不能寫成 helloMessage兵志。除此之外還需要注意組件類只能包含一個(gè)頂層標(biāo)簽,否則也會(huì)報(bào)錯(cuò)宣肚。
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World想罕!</h1>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
如果我們需要向組件傳遞參數(shù),可以使用 this.props 對(duì)象霉涨。
注意按价,在添加屬性時(shí), class 屬性需要寫成 className 笙瑟,for 屬性需要寫成 htmlFor 楼镐,這是因?yàn)?class 和 for 是 JavaScript 的保留字。
06 React State
React 把組件看成是一個(gè)狀態(tài)機(jī)(State Machines)往枷。通過(guò)與用戶的交互框产,實(shí)現(xiàn)不同狀態(tài),然后渲染 UI错洁,讓用戶界面和數(shù)據(jù)保持一致秉宿。
React 里,只需更新組件的 state墓臭,然后根據(jù)新的 state 重新渲染用戶界面(不要操作 DOM)蘸鲸。
以下實(shí)例中創(chuàng)建了 LikeButton 組件,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 方法,再次渲染組件技潘。
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 ? '喜歡' : '不喜歡';
return (
<p onClick={this.handleClick}>
你<b>{text}</b>我遥巴。點(diǎn)我切換狀態(tài)。
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
07 React Props
state 和 props 主要的區(qū)別在于 props 是不可變的享幽,而 state 可以根據(jù)與用戶交互來(lái)改變铲掐。這就是為什么有些容器組件需要定義 state 來(lái)更新和修改數(shù)據(jù)。 而子組件只能通過(guò) props 來(lái)傳遞數(shù)據(jù)值桩。
可以通過(guò) getDefaultProps() 方法為 props 設(shè)置默認(rèn)值摆霉。
Props 驗(yàn)證使用 propTypes,它可以保證我們的應(yīng)用組件被正確使用,React.PropTypes 提供很多驗(yàn)證器 (validator) 來(lái)驗(yàn)證傳入數(shù)據(jù)是否有效携栋。當(dāng)向 props 傳入無(wú)效數(shù)據(jù)時(shí)搭盾,JavaScript 控制臺(tái)會(huì)拋出警告。
08 React組件API
- 設(shè)置狀態(tài):setState
- 替換狀態(tài):replaceState
- 設(shè)置屬性:setProps
- 替換屬性:replaceProps
- 強(qiáng)制更新:forceUpdate
- 獲取DOM節(jié)點(diǎn):findDOMNode
- 判斷組件掛載狀態(tài):isMounted
replaceState()方法與setState()類似婉支,但是方法只會(huì)保留nextState中狀態(tài)鸯隅,原state不在nextState中的狀態(tài)都會(huì)被刪除。
props相當(dāng)于組件的數(shù)據(jù)流向挖,它總是會(huì)從父組件向下傳遞至所有的子組件中蝌以。當(dāng)和一個(gè)外部的JavaScript應(yīng)用集成時(shí),我們可能會(huì)需要向組件傳遞數(shù)據(jù)或通知React.render()組件需要重新渲染户誓,可以使用setProps()饼灿。
replaceProps()方法與setProps類似,但它會(huì)刪除原有帝美。
forceUpdate()方法適用于this.props和this.state之外的組件重繪(如:修改了this.state后)碍彭,通過(guò)該方法通知React需要調(diào)用render(),一般來(lái)說(shuō)悼潭,應(yīng)該盡量避免使用forceUpdate()庇忌,而僅從this.props和this.state中讀取狀態(tài)并由React觸發(fā)render()調(diào)用。
isMounted()方法用于判斷組件是否已掛載到DOM中舰褪〗哉睿可以使用該方法保證了setState()和forceUpdate()在異步場(chǎng)景下的調(diào)用不會(huì)出錯(cuò)。
09 React 組件生命周期
組件的生命周期可分成三個(gè)狀態(tài):
- Mounting:已插入真實(shí) DOM
- Updating:正在被重新渲染
- Unmounting:已移出真實(shí) DOM
生命周期的方法有:
- componentWillMount 在渲染前調(diào)用占拍,在客戶端也在服務(wù)端略就。
- componentDidMount 在第一次渲染后調(diào)用,只在客戶端晃酒。
- componentWillReceiveProps 在組件接收到一個(gè)新的prop時(shí)被調(diào)用表牢。
- shouldComponentUpdate 在組件接收到新的props或者state時(shí)被調(diào)用。在初始化時(shí)或者使用forceUpdate時(shí)不被調(diào)用贝次。
- componentWillUpdate 在組件接收到新的props或者state但還沒(méi)有render時(shí)被調(diào)用崔兴。
- componentDidUpdate 在組件完成更新后立即調(diào)用。
- componentWillUnmount 在組件從 DOM 中移除的時(shí)候立刻被調(diào)用蛔翅。
componentDidMount: function () {}敲茄;
10 AJAX
React 組件的數(shù)據(jù)可以通過(guò) componentDidMount 方法中的 Ajax 來(lái)獲取,當(dāng)從服務(wù)端獲取數(shù)據(jù)庫(kù)可以將數(shù)據(jù)存儲(chǔ)在 state 中山析,再用 this.setState 方法重新渲染 UI堰燎。
11 表單與事件
當(dāng)你需要從父組件中更新子組件的 state 時(shí),你需要在父組件通過(guò)創(chuàng)建事件句柄 (handleChange) 盖腿,并作為 prop (updateStateProp) 傳遞到你的子組件上爽待。
當(dāng)你需要從子組件中更新父組件的 state 時(shí)损同,你需要在父組件通過(guò)創(chuàng)建事件句柄 (handleChange) ,并作為 prop (updateStateProp) 傳遞到你的子組件上鸟款。
12 React Refs
React 支持一種非常特殊的屬性 Ref 膏燃,你可以用來(lái)綁定到 render() 輸出的任何組件上。
這個(gè)特殊的屬性允許你引用 render() 返回的相應(yīng)的支撐實(shí)例( backing instance )何什。這樣就可以確保在任何時(shí)間總是拿到正確的實(shí)例组哩。