非元素属性
不是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);