React组件实例的三大属性及事件处理
0. state 0. props 0. refs与事件处理
既然是实例属性,在不用hooks的情况下,只能通过类式组件来使用,所以本章例子都会用类式组件举例
⭐第一个属性:state
state属性中存放着组件的状态,或者说是数据更好理解一些,它里面的值是对象形式(包含多个key-value的组合),我们通过更新组件的state来更新对应的页面显示(重新渲染组件)
在我们创建好的组件实例中,已经有了state属性存在,但其内容为null,那么我们创建组件时,如何在state中定义数据呢?
答:通过构造器添加state状态,或直接对state进行赋值(更推荐)
//创建组件
class MyCpn extends React.Component{
constructor(props){
super(props)
//方式一:通过构造器操作
this.state = {myState:'hello!'}//在这里添加更改state内容
}
//方式二:直接操作
state = {myState:'hello!'}
render(){
return <h1>{this.state.myState}</h1>//在这里进行调用
}
}
这样,我们就完成了state的初始化以及数据读取调用
注意: state中的属性一旦在构造器中定义,不可直接更改,否则响应式会失效,我们应通过其内置API:setState()
进行状态的更改
⭐第二个属性:props
类式组件中使用props
上面的state是创建组件时就定义好了内容,如果我们想要在调用组件时再传入状态,就要用到props啦!
props同样也是组件实例上的属性,其状态的传入方式:
ReactDOM.render(<MyCpn name="何小幸" age="18"/>,document.getElementById('app'));
这样,何小幸和18都传入了组件中,成为prop属性中的状态,我们在组件中通过this.props.name/age
就可以取到对应的属性。
如果属性有很多呢?
简化写法:
const info = {name:'何小幸',age:18,sex:"unkonwn",tel:'137...',addr:'山西太原',birth:'010214'}
ReactDOM.render(<MyCpn {...info}/>,document.getElementById('app'))
这样info对象中的数据都会分别传入组件中
限制props中属性的类型与设置默认值
在React版本15.5.0以前,我们使用组件.propTypes
来限制属性类型:
//第一种写法:在类外侧定义
MyCpn.propTypes = {
name:React.PropTypes.string
}
//第二种写法:在类内侧定义
class MyCpn extends React.Component{
static propTypes = {
name:React.PropTypes.string
}
//其余省略
}
在新版本中,我们需要引入对应的prop-types库:
npm install prop-types --save
import PropTypes from 'prop-types';
然后直接通过PropTypes对象来使用:
MyCpn.propTypes = {
name:PropTypes.string
}
如果传入的value不符合对应类型,控制台就会爆红
这里要注意:string和number都是小写,函数类型写为func
设置属性为必填项:name:PropTypes.string.isRequired
设置默认值:
//第一种写法:在类外侧定义
MyCpn.defaultProps = {
sex:'不明'
}
//第二种写法:在类内侧定义
class MyCpn extends React.Component{
static defaultProps = {
name:React.PropTypes.string
}
//其余省略
}
props属性是只读的
当你写了构造器时
在你写了构造器时,需要将props作为参数传入,并在构造器中调用super(),同时也要为super传入props参数,否则就会产生props属性丢失问题(通过this.props)无法获取属性
写法:
constructor(props){
super(props);
//...
}
如果你并不需要在构造器中通过this.props获取其属性,那么完全可以不用写
函数式组件中使用props
函数式组件中无法绑定属性,我们就要通过参数的形式进行传递:
function MyCpn(props){
//...
}
在调用组件时,传入的属性就会自动作为参数进行传递,在组件内通过props就可获取。
由于函数内不能使用static关键字,所以如果想要对props中的内容进行限制,只能使用在外侧的方式:
MyCpn.propTypes = {
name:PropTypes.string
}
⭐第三个属性:refs
想知道refs属性,先来看看ref属性,ref类似于id,可以写在标签中作为其唯一标识符:
<input ref='myInput' type='text'/>
这样ref就标识了该input标签
refs属性则是绑定在组件上的属性,为对象类型,它会为我们收集所有标注ref属性的标签,统一以refValue:DomEle
的形式存在refs中:
注:refs为我们收集到的不是虚拟DOM,而是真实DOM