组件的属性是可以接收任何值的,但有时候我们希望对外界父级组件传递进来的属性数据进行限定,比如希望name属性不能缺少、onClick属性必须是函数类型等,这对确保组件被正确使用非常有意义。为此React引入了propTypes机制。React.PropTypes提供各种验证器(validator)来验证传入数据的有效性。当向props传入无效数据时,React会在JavaScript控制台抛出警告。
我们来作一个小列子,看一下PropTypes的用法。
<script type="text/babel">
class HelloWorld extends React.Component{
render(){
return(
<h1> {this.props.title}</h1>
)
}
}
ReactDOM.render(<HelloWorld title="React"/>,document.getElementById('div'))
</script>
这是我们之前使用prop传递的小demo,现在改变一下,为他设置限制条件
刚才卡了一下,因为我使用的是15版本的react,并且是类写法,所以从改写上面有点小bug,贴下代码吧
<script type="text/babel">
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1> {this.props.title}</h1>
)
}
}
HelloWorld.propTypes={
title:React.PropTypes.string.isRequired,
}
var data="123"
ReactDOM.render(<HelloWorld title={data}/>,document.getElementById('div'))
</script>
ES5写法的React.createClass是把propTypes属性写入对象中,我原以为可以在constructor中类似State的写法插入此属性,但是发现不行,所以这个要注意一下!
15版本只是为了接触更多的api学习,之后使用脚手架会重新撸一遍!当然了这里的propTypes已经被react单独拎出了一个package,需要import react里的‘prop-types’
OK 回到主题 在ReactDOM.render渲染的时候我特意使用了差值,然后我给title的限制是首先必须是字符串且必选,此时浏览器没啥问题,如果我将data换成123 就会爆出警告
一般常见的数据类型控制
propTypes: {
myArray: React.PropTypes.array,
myBool: React.PropTypes.bool,
myFunc: React.PropTypes.func,
myNumber: React.PropTypes.number,
myString: React.PropTypes.string,
requiredFunc: React.PropTypes.func.isRequired //这里如果不是必须的话去掉isRequired即可
}
如果你实在是懒得判断可以使用any大法PropTypes.any
介绍一下arrayof方法,如果传递的是数组就需要使用arrayof方法检测数组项的数据类型
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1>{this.props.array}</h1>
)
}
}
var arr=[1,2,3,4]
HelloWorld.propTypes={
array:React.PropTypes.arrayOf(React.PropTypes.number)
}
ReactDOM.render(<HelloWorld array={arr}/>,document.getElementById('div'))
如果arr有一项不是num就会报警告
由于数组是很强大的,可以存储所有属性,如果我们不用any大法就可以使用oneOfoneOfType
var arr=[1,2,3,'4',[5,6]]
HelloWorld.propTypes={
array:React.PropTypes.arrayOf(React.PropTypes.oneOfType([React.PropTypes.string,React.PropTypes.number,React.PropTypes.array]))
}
只要满足其中的一项即可,相同的也存在oneOf,有其中一个值即可的方法
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1>{this.props.array}</h1>
)
}
}
var number=1
HelloWorld.propTypes={
array:React.PropTypes.oneOf([1,2,3,4,5])
}
ReactDOM.render(<HelloWorld array={number}/>,document.getElementById('div'))
这里偷懒没改变量名,此时number如果是1,2,3,4,5中的任一一个就不会报warn
再介绍一下如果是obj的检测
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1>{this.props.myobj.title},{this.props.myobj.arr}</h1>
)
}
}
var myobj={title:'HelloWorld',arr:['React','Vue']}
HelloWorld.propTypes={
myobj:React.PropTypes.shape({
title:React.PropTypes.string,
arr:React.PropTypes.arrayOf(React.PropTypes.string)
})
}
ReactDOM.render(<HelloWorld myobj={myobj}/>,document.getElementById('div'))
方法是一样的,注意obj的shape方法即可
还有一个自定义验证,其实就是一个函数,多数使用正则来验证,简单写个例子吧
<script type="text/babel">
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1>{this.props.email}</h1>
)
}
}
HelloWorld.propTypes={
email:function (props,propName,componentName) {
if(){
retun new Error()
}
}
}
ReactDOM.render(<HelloWorld email={}/>,document.getElementById('div'))
</script>
首先需要注意的是三个参数,在这里props是包含prop的props对象,propName是prop的属性名,componentName是props所在的组件名称,函数的返回值是一个Error对象
<script type="text/babel">
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1>{this.props.email}</h1>
)
}
}
HelloWorld.propTypes={
email(props,propName,componentName){
if(!/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test(props[propName])){
return new Error('组件' + componentName+ '里的属性' + propName + '不符合邮箱的格式');
}
}
}
ReactDOM.render(<HelloWorld email={1351985377}/>,document.getElementById('div'))
</script>
这改成了ES6写法,正则是百度的(*^▽^*)
props相当于属性集合,所以这里是关联数组的写法
网友评论