React是一個用于創(chuàng)建UI組件的框架,它的核心就是組件
組件實際上并不難理解,在傳統(tǒng)的桌面編程中,組件實際上就是一個個的控件,開發(fā)者無須編寫代碼就可以直接從IDE的控件箱中拖控件來創(chuàng)建簡單的應(yīng)用程序。而對應(yīng)到前端來說,我們一開始見到的一些組件可能是來自Dreamweaver自帶的一些簡單的web小控件,例如單行文本框,單選/多選框以及下拉列表等等,實際上這些控件所提供的功能對前端開發(fā)者來說太過于簡陋,甚至可以說是丑陋。當(dāng)我們脫離了刀耕火種的時代,前端組件化需求就顯得十分迫切
在當(dāng)下有很多框架實現(xiàn)了組件化,例如非?;鸨?code>bootstrap,有一點需要區(qū)分的是前端組件化(Web Components)和模塊化(module),它們是不同的概念。關(guān)于這兩點的具體區(qū)別將在后續(xù)文章中詳細介紹,我們首先應(yīng)該關(guān)注的是組件化
React中的組件
在上一篇文章中,我們使用React創(chuàng)建了一個簡單的應(yīng)用程序,它可以在頁面上渲染出"Hello World!"。其中React.createClass所創(chuàng)建的Hello對象就是一個組件,我們可以使用同樣的方法創(chuàng)建出更多不同功能的組件以便于重復(fù)使用,而且組件可以相互嵌套,例如:
var Hello =React.createClass({
render:function (){
return (
<div>
<h1>This is my first web components!</h1>
<Keke></Keke> {/*Keke作為子組件被嵌套在Hello組件中*/}
</div>
)
}
});
var Keke=React.createClass({
render:function (){
return (
<h2>ReactJS is good!</h2>
)
}
});
這個例子中,首先創(chuàng)建了一個Hello組件,它包含一個h1標(biāo)簽,然后創(chuàng)建了一個Keke組件,包含一個h2標(biāo)簽,在Hello組件中可以將Keke組件像一個普通的HTML標(biāo)簽一樣插入進來,語法依然像HTML一樣可以是閉合標(biāo)簽<Keke></Keke>也可以是自閉合標(biāo)簽<Keke/>,這也是JSX語法的特點之一。
使用React創(chuàng)建組件可以任意的嵌套,每個組件的UI以及邏輯相互獨立,拿掉任何一個組件不會影響應(yīng)用程序的正常運行。這樣一來可以將一個web頁面切分為很多個組件,非常便于后期維護。
屬性與狀態(tài)
在React為數(shù)不多的概念中,屬性(props)與狀態(tài)(state)可能是最讓初學(xué)者頭疼的,在一個React組件中,它們是這樣工作的。
var myName="Sakura";
//定義myName變量
var MyComponents=React.createClass({
getInitialState:function (){ {/*初始化state*/}
return {
user:this.props.user {/*將user屬性賦值給user狀態(tài)*/}
}
},
render:function (){
return (
<div>
<h1>My name is {this.state.user}</h1>
{/*user狀態(tài)可以使用this.state獲取到*/}
</div>
)
}
});
ReactDOM.render(
{/*將myName變量作為MyComponents組件的user屬性傳入*/}
<MyComponents user={myName}/>,
document.getElementById("app")
);
這個例子中,this.props是組件的屬性,組件的屬性props必須通過父組件向下傳遞,在ReactDOM.render方法中,我們把myName變量作為一個屬性傳遞給了MyComponents組件,并且命名為user,而在這個組件內(nèi)部,我們可以使用this.props.user得到這個屬性。
狀態(tài)是React組件中的一個對象,用于存放組件相關(guān)數(shù)據(jù)。React把用戶界面當(dāng)做一個狀態(tài)機,狀態(tài)的更新會引起組件的重新渲染,從而使數(shù)據(jù)與界面保持一致。getInitialState方法用于定義狀態(tài)的初始值,在這個例子中user狀態(tài)的初始值是由傳入的user屬性決定的。狀態(tài)與界面息息相關(guān),一切與界面相關(guān)的數(shù)據(jù)都應(yīng)存放在state中,更新state可以使用this.setState方法,React不允許直接通過this.state.xxx=xxx的方式直接修改state。
props與state兩者的區(qū)別是:props是用于父組件向子組件傳遞數(shù)據(jù)的通道,而state則是組件存放自身相關(guān)信息的一個對象
單向數(shù)據(jù)流
React的數(shù)據(jù)是自頂向下的單向數(shù)據(jù)流,在一個React應(yīng)用程序中,數(shù)據(jù)由父組件通過props自頂向下傳遞給子組件,子組件接收到數(shù)據(jù)后,可以將props中的屬性作為自身的一個狀態(tài)(state)用于渲染界面。