一、復(fù)習(xí)
約束組件(表單對于input(tyoe=text)等等用value,單選框和多選框設(shè)置checked)
組件內(nèi)部的信息狀態(tài)交由組件管理,由state狀態(tài)來管理;
value或checked來設(shè)置默認狀態(tài)值,獲取組件的值也就是狀態(tài)。
onChange方法來更改組件內(nèi)部的狀態(tài);非約束組件(表單)
組件(元素)的內(nèi)部信息交由元素自身管理;
defaultValue或defaultChecked來設(shè)置默認值,獲取值通過ref設(shè)置來獲取;
ref是非元素屬性,獲取虛擬dom的快捷方式;ref="name"
this.refs.name來獲取,對象就是虛擬dom;非元素屬
- key 當循環(huán)創(chuàng)建列表元素的時候,會使用該屬性來標識;
- ref 獲取元素的快捷方式,獲取通過this.refs來獲取;
- dangerouslySetInnerHTML 設(shè)置元素內(nèi)容的值,接收一個對象,對象有一個屬性__html,用來設(shè)置元素的內(nèi)容,插入的值是任意字符串,比如html標簽,可以摻入行內(nèi)式的樣式等;
- 父組件向子組件信息傳遞
通過父組件對子組件添加屬性來實現(xiàn)的,子組件通過this.props來獲取父組件的消息;
第一種情況:添加的屬性是一個固定值(字符串),父組件每次更新的時候,子組件的屬性不會變化;
第二種情況:添加的屬性是一個父組件中的變量,父組件每次更新的時候,如果該變量更新了,子組件也會更新;
第三種情況:添加屬性是父組件中的狀態(tài),父組件每次更新,該方法不會更新,但是子組件內(nèi)部發(fā)生交互的時候,可能會調(diào)用該父組件傳遞的方法,在該方法中如果改變了父組件的狀態(tài),(子組件向父組件傳遞信息);
第四種情況:添加的屬性是父組件中的屬性,此時父組件屬性更新了,子組件會更新;
第五種情況:添加的屬性是父組件中的狀態(tài),此時父組件狀態(tài)更新了,子組件會更新;
- 獲取組件中的元素
ReactDOM.findDOMNode(this) 獲取的是整個組件
ReactDOM.findDOMNode(this.refs.name) 獲取的ref元素
========================================================================
二、兄弟組件之間的信息傳遞(雙向綁定)
每個子組件都有自己的完整空間,彼此沒有聯(lián)系,因此他們之間最大的難題就是信息的傳遞;
我們知道父組件可以和子組件通信,通過設(shè)置子組件的屬性;
父組件除了可以向子組件傳遞固定值,屬性值,狀態(tài)值,還可以傳遞函數(shù);
父組件的方法如果綁定在了子組件的元素事件上,那么在該方法中,事件對象的target是組件綁定事件的元素,e.target.value就是要獲取的子組件的值;而this則是父組件自己,通過this.setState來講子組件的值傳遞給另一個子組件;
該方法需要通過共同的父組件實現(xiàn);
如果一個兄弟組件向另一個兄弟組件傳遞信息,流程是由該兄弟組件向父組件傳遞信息,再由該父組件代理向另一個子組件傳遞;可以學(xué)習(xí)Project的代碼;
var InputMsg = React.createClass({
render:function(){
// console.log(this.props.changeMsg)如果把父組件傳遞的這個函數(shù)綁定到子組件的onChange事件上會發(fā)生什么呢?
return (
<div>
<input type="text" onChange={this.props.changeMsg}/>
</div>
)
}
})
var ShowMsg = React.createClass({
render:function(){
return (
<div>
<ul>
<p>{this.props.msg}</p>
</ul>
</div>
)
}
})
var Main = React.createClass({
getInitialState:function(){
return {
msg:'world'
}
},
changeMsg:function(e){
//事件對象是子組件中的Input,而this指向的是父組件自己;
// console.log(111,e,222,this)
// console.log(e.target.value)//該值就是子組件InputMsg的值,也是要傳遞給ShowMsg的值
var value = e.target.value;
this.setState({
msg:value
})
},
render:function(){
return (
<div className="main">
<InputMsg changeMsg={this.changeMsg}/>
<ShowMsg msg={this.state.msg}/>
</div>
)
}
})
ReactDOM.render(<Main />,document.getElementById('app'))
=======================================================================
混合
react支持混合,將混合中的方法復(fù)制到組件對象中,這樣組件對象就可以使用該方法了;
在組件外部定義個對象
var MethodMixin = {//混合方法,把公用的部分提取出來
getData:function(url,callback){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
//
if (xhr.readyState == 4){
if(xhr.status == 200){
var obj = JSON.parse(xhr.responseText)
callback(obj)
} else{
console.log('請求失敗')
}
}
}
xhr.open("GET",url,true);
xhr.send(null);
}
}
組件內(nèi)部調(diào)用,注意:這是一個數(shù)組,我們們可以通過混合復(fù)制多個對象上的屬性方法,因此混合可以看作是一種多繼承;es6中實現(xiàn)了繼承,就不要用這個方法了;
mixins: [MethodMixin],//調(diào)用混合
使用混合當中的方法
componentDidMount:function(){
var me = this;
this.getData('data/start.json',function(res){//通過混合就能this.調(diào)用混合對象的getData方法
// console.log(res)
me.setState({
article:res,
aside:me.asideAdaptor(res)
})
})
}
========================================================================================================
組件提煉
通常一個組件做一件事,方便復(fù)用;