這個例子是React官方文檔里面的,代碼也在CodePen,例子非常簡單,展示了React組件開發(fā)的基本過程,這里將這個例子進(jìn)行分析記錄,當(dāng)做學(xué)習(xí)筆記吧!首先看代碼:
//HTML
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
//JS
function FormattedDate(props) {
return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<FormattedDate date={this.state.date} />
</div>
);
}
}
function App() {
return (
<div>
<Clock />
<Clock />
<Clock />
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
程序的運行過程:
1、在html里面定義一個div,id為root
2、 調(diào)用ReactDOM.render使用App渲染id為root的div,這里會調(diào)用函數(shù)App
3、函數(shù)App返回的是什么呢?不是字符串,也不是HTML,而是JSX,JSX是JavaScript語法的擴(kuò)展,Babel會將JSX編譯成React.createElement()的調(diào)用,這里可以簡單看成返回界面布局就行了
4、在函數(shù)App返回的布局中,有三個Clock組件,Clock組件繼承React.Component,當(dāng)被傳入ReactDOM.render中后,會調(diào)用Clock構(gòu)造方法
5、在Clock構(gòu)造方法可以接收一個props, 它來保存組件的組件的屬性,這里并沒有傳入任何屬性值,在構(gòu)造方法里面初始化組件的狀態(tài)state,給狀態(tài)設(shè)置了date字段
6、接下來會調(diào)用Clock的render方法來渲染組件,render方法也是返回了JSX,里面有Hello World的標(biāo)題,并且調(diào)用FormattedDate函數(shù),傳入?yún)?shù)date,返回時間的JSX,在FormattedDate函數(shù)里通過props.date獲取傳入的date
7、這時候就已經(jīng)可以看到三個Clock顯示時間了
8、那時間怎么自動更新的呢?當(dāng)Clock被插入DOM時,會觸發(fā)componentDidMount,當(dāng)Clock從DOM移除時,會觸發(fā)componentWillUnmount,所以在componentDidMount調(diào)用時開始定時更新,在componentWillUnmount關(guān)閉定時更新
9、定時更新會調(diào)用tick方法,tick方法調(diào)用setState來更新date字段
10、setState方法會觸發(fā)render方法的重新調(diào)用,進(jìn)而更新時間
由于筆者之前是做移動端開發(fā),React的組件的概念跟iOS和Android的View的概念基本一致,甚至一些方法可以對應(yīng)的上,如componentDidMount和componentWillUnmount可對應(yīng)Android View中的onAttachedToWindow和onDetachedFromWindow, Clock中的render可對應(yīng)Android View中的onDraw??梢钥闯鰜砭幊汤砟疃际谴笸‘悺=M件化實際上就是模塊化,提高了代碼的復(fù)用性和可維護(hù)性。