無(wú)狀態(tài)函數(shù)式組件
創(chuàng)建純展示組件辑舷,只負(fù)責(zé)根據(jù)傳入的props
來(lái)展示卖哎,不涉及到要state
狀態(tài)的操作,是一個(gè)只帶有一個(gè)render
方法的組件類(lèi)
創(chuàng)建形式如下:
function HelloComponent(props) {
return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="yourName" />, mountNode)
特點(diǎn):
- 組件不會(huì)被實(shí)例化,整體渲染性能得到提升
- 組件不能訪問(wèn)
this
對(duì)象 - 組件無(wú)法訪問(wèn)生命周期的方法
- 無(wú)狀態(tài)組件只能訪問(wèn)輸入的
props
三椿,同樣的props
會(huì)得到同樣的渲染結(jié)果,不會(huì)有副作用
無(wú)狀態(tài)組件使得代碼結(jié)構(gòu)更加清晰葫辐,減少代碼冗余搜锰,在開(kāi)發(fā)過(guò)程中,盡量使用無(wú)狀態(tài)組件
React.createClass
是ES5的原生的JavaScript來(lái)實(shí)現(xiàn)的React
組件
該例子實(shí)現(xiàn)了一個(gè)交互列表耿战,用戶(hù)輸入信息蛋叼,按回車(chē)后觸發(fā)鍵盤(pán)事件將獲取到的輸入值渲染生成列表項(xiàng),輸入信息的數(shù)量可以是任意多個(gè)
具體形式如下:
var Greeting = React.createClass({
getInitialState: function () {
return {
work_list: []
};
},
render: function () {
return (
<div>
<input type="text" ref="myWork" placeholder="What need to be done?" onKeyUp={this.Enter}/>
<ul>
{
this.state.work_list.map(function (textValue) {
return <li key={textValue}>{textValue}</li>;
})
}
</ul>
</div>
);
},
Enter: function (event) {
var works = this.state.work_list;
var work = this.refs.myWork.value;
if (event.keyCode == 13) {
works.push(work);
this.setState({work_list: works});
this.refs.myWork.value = "";
}
}
});
給文本框增加onKeyUp
監(jiān)聽(tīng)鍵盤(pán)事件
組件在插入頁(yè)面前其實(shí)是在虛擬 DOM 中的表示剂陡,因此狈涮,在渲染成最終實(shí)際的 DOM 前,不能通過(guò)直接訪問(wèn)組件內(nèi)的元素來(lái)試圖獲取它的屬性鹏倘。文本輸入框用于獲取用戶(hù)的輸入薯嗤。這時(shí)就必須獲取真實(shí)的 DOM 節(jié)點(diǎn),虛擬 DOM 是拿不到用戶(hù)輸入的纤泵。為了做到這一點(diǎn)骆姐,我們?cè)谖谋据斎肟蛱砑恿艘粋€(gè)ref
屬性 myWork,然后通過(guò)this.refs.myWork
就指向這個(gè)虛擬 DOM 的子節(jié)點(diǎn)捏题,這樣就可以通過(guò)this.refs.myWork.value
獲取到它的值
特點(diǎn):
- React.createClass會(huì)自綁定函數(shù)方法導(dǎo)致不必要的性能開(kāi)銷(xiāo)
- React.createClass的mixins不夠自然玻褪、直觀
React.Component
React.Component
是以ES6的形式來(lái)創(chuàng)建react
的組件的,是React目前極為推薦的創(chuàng)建有狀態(tài)組件的方式公荧,相對(duì)于 React.createClass
可以更好實(shí)現(xiàn)代碼復(fù)用带射。將上面React.createClass
的形式改為React.Component
形式如下:
class Greeting extends React.Component{
constructor (props) {
super(props);
this.state={
work_list: []
}
this.Enter=this.Enter.bind(this); //綁定this
}
render() {
return (
<div>
<input type="text" ref="myWork" placeholder="What need to be done?" onKeyUp={this.Enter}/>
<ul>
{
this.state.work_list.map(function (textValue) {
return <li key={textValue}>{textValue}</li>;
})
}
</ul>
</div>
);
}
Enter(event) {
var works = this.state.work_list;
var work = this.refs.myWork.value;
if (event.keyCode == 13) {
works.push(work);
this.setState({work_list: works});
this.refs.myWork.value = "";
}
}
}
關(guān)于this
React.createClass
創(chuàng)建的組件,其每一個(gè)成員函數(shù)的this
都有React
自動(dòng)綁定循狰,任何時(shí)候使用窟社,直接使用this.method
即可券勺,函數(shù)中的this
會(huì)被正確設(shè)置
React.Component
創(chuàng)建的組件,其成員函數(shù)不會(huì)自動(dòng)綁定this
灿里,需要手動(dòng)綁定关炼,否則this
不能獲取當(dāng)前組件實(shí)例對(duì)象
React.Component三種手動(dòng)綁定this的方法
- 在構(gòu)造函數(shù)中綁定
constructor(props) {
super(props);
this.Enter = this.Enter.bind(this);
}
- 使用bind綁定
<div onKeyUp={this.Enter.bind(this)}></div>
- 使用arrow function綁定
<div onKeyUp={(event)=>this.Enter(event)}></div>
我們?cè)趯?shí)際應(yīng)用中應(yīng)該選擇哪種方法來(lái)創(chuàng)建組件呢?
- 只要有可能匣吊,盡量使用無(wú)狀態(tài)組件創(chuàng)建形式
- 否則(如需要state儒拂、生命周期方法等),使用
React.Component
這種es6形式創(chuàng)建組件