React(七)—— Prop属性验证

2019-02-22  本文已影响2人  感觉不错哦
组件的属性是可以接收任何值的,但有时候我们希望对外界父级组件传递进来的属性数据进行限定,比如希望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相当于属性集合,所以这里是关联数组的写法

需要注意的是现在这玩意已经在15.5之后弃用了,如果使用需要单独的引入包 后续再讲吧
上一篇下一篇

猜你喜欢

热点阅读