非元素屬性
不是dom元素的屬性,我們稱之為非元素屬性
- key: key={i} / key={index} 寫在元素節點attr上,主要是用來表示重復的元素不同的標識,通過設置Key讓每個列表元素獲取了id,react會最終轉化為data-reactid='0.1XX',對于react來說是可以通過id的唯一不同來識別是否要更新狀態;
- rel :用來在組件方法中更方便的獲取組件內部元素的一個屬性;
- dangerouslySetInnerHTML: 用來設置元素的內容,效果如同<div>內容</div>,這個屬性比較特殊,對應的值是一個對象,__html屬性對應的值會插入到元素內部;
獲取事件本身可以傳入e,通過e.target獲得;
例如:
var Search = React.createClass({
clickBtn:function(e){
//獲取btn自己
console.log(e.target)
},
render:function(){
return(
<div className="search">
<div className="search-group">
<input ref="searchInput" type="text"/>
<button onClick={this.clickBtn}>百度一下</button>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
輸出:
<button data-reactid=".0.0.1">百度一下</button>
如果想通過點擊事件獲取input就應該要給Input設置ref,調用this.refs來獲取:
var Search = React.createClass({
clickBtn:function(e){
//獲取input的值
console.log(this.refs.searchInput.value)
},
render:function(){
return(
<div className="search">
<div className="search-group">
<input ref="searchInput" type="text"/>
<button onClick={this.clickBtn}>百度一下</button>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
重新渲染頁面,輸入一些內容,點擊按鈕就看到值被輸出了。
如果我們想在元素內用style設置樣式,還記得之前的課程有說過吧,先來實現一下,我們要在btn按鈕后面加上一個手寫二字:
var Search = React.createClass({
clickBtn:function(e){
console.log(this.refs.searchInput.value)
},
render:function(){
var style = {
color:'green'
}
return(
<div className="search">
<div className="search-group">
<input ref="searchInput" type="text"/>
<button onClick={this.clickBtn}>百度一下</button>
<span style={style}>手寫</span>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
我們還可以采用dangerouslySetInnerHTML:來設置:
var Search = React.createClass({
clickBtn:function(e){
//獲取input的值
console.log(this.refs.searchInput.value)
},
//dangerouslySetInnerHTML={content}
render:function(){
var content = {
__html:'<span style="color:red;">手寫<span>'
}
return(
<div className="search">
<div className="search-group">
<input ref="searchInput" type="text"/>
<button onClick={this.clickBtn}>百度一下</button>
<span dangerouslySetInnerHTML={content}></span>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
可以看出手寫兩個字也在設置之內:
<span dangerouslySetInnerHTML={content}></span>
var content = {
__html:'<span style="color:red;">手寫<span>'
}
==================================================================
約束性組件與非約束性組件
通常是對表單元素而言的
約束性組件的狀態由組件自身管理,非約束性組件的狀態由元素自身管理
非約束性組件,每一次獲取input元素的數據,都要通過this.refs.searchInput來獲取,這種方式,元素狀態和信息都保存在元素本身,因此它是一種非約束性元素;
defaultValue、placeholder和value
我們可以通過defaultValue來設置元素的默認值,用placeholder也可以設置,區別在于placeholder只是顯示數據文案,沒有對value處理,而defaultValue是對元素的value進行設置的,可以獲取到,如果直接用value會報錯;
var Search = React.createClass({
clickBtn:function(e){
var inp = this.refs.searchInput;
console.log(inp.value)
},
render:function(){
return(
<div className="search">
<div className="search-group">
<input ref="searchInput" type="text" defaultValue="用戶輸入的內容"/>
<button onClick={this.clickBtn}>百度一下</button>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
約束性組件
來看看約束性組件,它不再由表單元素自己控制了,而是交由組件的state狀態來控制,這樣會更加靈活。
var Search = React.createClass({
getInitialState:function(){
return {
inp:'默認的狀態'
}
},
inpChange:function(e){//input元素的值現在交由state狀態來管理
//這樣我們可以通過state來做一些事,更靈活的控制
if(e.target.value.indexOf('a') > -1){
return
}
console.log(e.target.value)
this.setState({
inp:e.target.value
})
},
render:function(){
return (
<div className="search">
<div className="search-group">
{/*將input元素的狀態寫入*/}
<input type="text" value={this.state.inp} onChange={this.inpChange}/>
<button>百度一下</button>
<p>{this.state.inp}</p>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
我們在按鈕下方增加了一個p元素,通過state就能做到雙向綁定;
注意:我們要通過state來管理,首先必須通過getInitialState函數來返回一個對象,初始值屬性名和值自定義,然后給需要控制的元素添加對應的state綁定,例如該例子對input設置了value={this.state.inp} ,這樣還不夠,狀態是用來捕獲更新的,所以我們需要有個事件來觸發state更新,所以我們可以給button來設置onClick事件,也可以對input元素本身設置一個onChange事件來設置狀態的更新;
==================================================================
拓展代碼,當點擊百度一下,通過異步獲取state的值;
var Search = React.createClass({
getInitialState:function(){
return {
inp:'默認的狀態',
resText:''
}
},
inpChange:function(e){//input元素的值現在交由state狀態來管理
//這樣我們可以通過state來做一些事,更靈活的控制
if(e.target.value.indexOf('a') > -1){
return
}
console.log(e.target.value)
this.setState({
inp:e.target.value
})
},
clickBtn:function(){
var me = this;
setTimeout(function(){
me.setState({
resText:'這是搜索返回的結果'
})
},2000)
},
render:function(){
return (
<div className="search">
<div className="search-group">
{/*將input元素的狀態寫入*/}
<input type="text" value={this.state.inp} onChange={this.inpChange}/>
<button onClick={this.clickBtn}>百度一下</button>
<p >{this.state.resText}</p>
</div>
</div>
)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
這里用的setTimeout來模擬ajax異步獲取數據;
======================================================================
我們再來改造一下這段代碼,我們添加一個判斷,當input輸入的長度大于10,就在下方文本提示;
var Search = React.createClass({
getInitialState:function(){
return {
inp:'默認的狀態',
resText:''
}
},
inpChange:function(e){//input元素的值現在交由state狀態來管理
//這樣我們可以通過state來做一些事,更靈活的控制
if(e.target.value.indexOf('a') > -1){
return
}
//判斷長度給予警告信息
if(e.target.value.length > 10){
this.setState({
resText:'您輸入的內容長度大于10'
})
}else{
resText:''
}
console.log("this.state",this.state)
this.setState({
inp:e.target.value
})
},
clickBtn:function(){
var me = this;
setTimeout(function(){
me.setState({
resText:'這是搜索返回的結果'
})
},2000)
},
render:function(){
return (
<div className="search">
<div className="search-group">
{/*將input元素的狀態寫入*/}
<input type="text" value={this.state.inp} onChange={this.inpChange}/>
<button onClick={this.clickBtn}>百度一下</button>
<p >{this.state.resText}</p>
</div>
</div>
)
},
componentWillUpdate:function(nextProps,nextState){
console.log(nextProps,nextState,111)
}
})
ReactDOM.render(<Search />,document.getElementById('app'))
你會發現setState時你只需要設置你需要設置的哪個屬性即可,其它屬性并不會被刪除掉;
================================================================
下拉框
非約束性組件案例
var Select = React.createClass({//用非約束性組件的方式:defaultValue,ref
showResult:function(){
console.log(this.refs.selectVal.value)
},
render:function(){
return (
<div>
<button onClick={this.showResult}>result</button>
<select ref="selectVal" defaultValue="前端">
<option value="張藝興">張藝興</option>
<option value="鹿晗">鹿晗</option>
<option value="前端">前端</option>
</select>
</div>
)
}
})
ReactDOM.render(<Select />,document.getElementById('app'))
約束性組件實現上述案例(對比非約束性組件)
var Select = React.createClass({//用非約束性組件的方式:defaultValue,ref
showResult:function(){
console.log(this.refs.selectVal.value)
},
showResult2:function(){
console.log(this.state.sel)
},
changeSel:function(e){
console.log(e.target.value)
this.setState({
sel:e.target.value
})
},
getInitialState:function(){
return {
sel:'上海'
}
},
render:function(){
return (
<div>
<button onClick={this.showResult}>result</button>
<select ref="selectVal" defaultValue="前端">
<option value="張藝興">張藝興</option>
<option value="鹿晗">鹿晗</option>
<option value="前端">前端</option>
</select>
<button onClick={this.showResult2}>result</button>
<select value={this.state.sel} onChange={this.changeSel}>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="深圳">深圳</option>
</select>
</div>
)
}
})
ReactDOM.render(<Select />,document.getElementById('app'))
======================================================================
復選框
我們通過一個案例來學習checkbox
我們要知道checked是設置方法,true為選中,false為未選中;
var Checkbox = React.createClass({
showResult:function(){
// console.log(this.refs.codeA.value) 這個不對
console.log(this.refs.codeA.checked,1)
console.log(this.state.che,2)
},
cklickCheckbox:function(){
if(this.state.che){
this.setState({
che:false
})
}else{
this.setState({
che:true
})
}
},
getInitialState:function(){
return {
che:true
}
},
render:function(){
//非約束性組件,默認讓元素選中,defaultChecked=true ref=""
//約束性組件,state來設置true和false
return(
<div>
<button onClick={this.showResult}>查看結果</button>
<input ref="codeA" type="checkbox" defaultChecked='false'/>
<input type="checkbox" checked={this.state.che} onChange={this.cklickCheckbox}/>
</div>
)
}
})
ReactDOM.render(<Checkbox />,document.getElementById('app'))
==============================================================================
我們看下這段代碼:
cklickCheckbox:function(){
if(this.state.che){
this.setState({
che:false
})
}else{
this.setState({
che:true
})
}
}
其實這里有更簡單的方法:
cklickCheckbox:function(e){
this.setState({
che:e.target.checked
})
}
===========================================================================
我們來復習一下:
約束性組件:
select:通過state狀態的改變來控制value,默認value直接設置value獲取state狀態;
radio&checkbox:通過state狀態的改變來控制checked,默認checked直接設置checked獲取state狀態;;
非約束性組件:
select:設置ref,通過refs來獲取該元素value,要設置默認值就要設置defaultValue;
redio&checkbox:設置ref,通過refs來獲取該元素checked,要設置默認值就要設置defaultChecked;
============================================================================
獲取組件元素方法
findDOMNode
注意:組件在創建有五個階段的聲明周期,如果要獲取組件元素需要在componentDinMount 組件構建完成下才能獲取,所以findDOMNode應該這樣使用:
componentDidMount:function(){
var dom = ReactDOM.findDOMNode(this);
console.log(dom)
}
把這段代碼放到上面復選框的案例中,控制臺輸出結果為:
<div data-reactid=".0">
<button data-reactid=".0.0">查看結果</button>
<input type="checkbox" checked="" data-reactid=".0.1">
<input type="checkbox" checked="" data-reactid=".0.2">
</div>
這個方法支持通過ref來獲取:
var dom = ReactDOM.findDOMNode(this.refs.codeA);