• React: React的属性验证机制


    一、简介

    在开发中,属性变量类型的验证,几乎是任何语言都必须关注的问题,因为如果传入的数据类型不对,轻者程序运行仅仅是给出警告⚠️,严重的会直接导致程序中断,APP闪退或者web页面挂掉,这是很严重的bug问题。如我们所知,JavaScript是一种弱类型的语言,这意味着开发者可以随意地修改变量值的数据类型,而且JavaScript虚拟机对此操作并不会产生异议,虽然这种机制大大地提高了编程的灵活性,但是也隐藏了一个极大的crash风险。React组件为此提供了一种声明和验证属性类型的方法,称为自动属性验证机制。这种机制将会大幅度减少调试时间,能够及时把不正确的属性类型触发警告⚠️,以便开发者准确快速的定位bug,然后进行修复。

    二、验证器类型

    React内置了自动属性验证器,如下所示:

    数组类型     React.PropTyps.array
    
    布尔类型     React.PropTyps.bool
    
    函数类型     React.PropTyps.func
    
    数字类型     React.PropTyps.number
    
    对象类型     React.PropTyps.object
    
    字符串类型   React.PropTyps.string

    React也支持自定义属性验证器,可以使用typeof字段和“===”进行判断并抛出异常,例如:

    布尔类型 (props, propName) => (typeof props[propName] === "boolean") ?  null : new Error(`${propName} is not boolean`)
    
    函数类型 (props, propName) => (typeof props[propName] === "function") ?  null : new Error(`${propName} is not function`)
    
    数字类型 (props, propName) => (typeof props[propName] === "number") ?  null : new Error(`${propName} is not number`)
    
    对象类型 (props, propName) => (typeof props[propName] === "object") ?  null : new Error(`${propName} is not object`)
    
    字符串类型 (props, propName) => (typeof props[propName] === "string") ?  null : new Error(`${propName} is not string`)

    字符类类型和长度限制嵌套 (props, propName) =>
    (typeof props[propName] === 'string') ?
    ((props[propName].length > 5) ? new Error("长度超过5") : null) : new Error(`${propName} is not sring`)

    三、验证器声明

    React中对属性类型的声明使用了关键字propTypes。对于createClass组件、ES6类组件和无状态函数式组件,它们的声明方式有所区别,如下所示:

    createClass组件:

    //创建组件
    const Component = React.createClass({
        //属性验证声明
        propTypes: {
            title: React.PropTypes.string,
            items: React.PropTypes.array
        }
       .........   })

    ES6类组件:

    //创建组件
    class Component extends React.Component{
        .........     
    }
    //属性验证声明
    Component.propTypes = {
        title: React.PropTypes.string, 
        items: React.PropTypes.array
    }

    无状态函数式组件:

    //创建组件
    const Component = ({title,items}) => {
        .......
    }
    //属性验证声明
    Component.propTypes = {
        title: React.PropTypes.string,
        items: React.PropTypes.array
    }

    四、验证器属性限制

    React中,在没有提供属性数据的情况下渲染组件会导致JavaScript报错,从而拖垮整个Web应用。对于这种数据缺少的错误,React属性验证器提供了isRequired字段要求属性数据是必须项,如果不填或者为空,React将会在触发错误之前就在控制台发出警告信息,提醒开发者异常原因。如下:

    //创建组件
    const Component = React.createClass({
        //属性验证声明
        propTypes: {
            title: React.PropTypes.string.isRequired,
            items: React.PropTypes.array.isRequired
        }
       .........  
    })

    五、简单示例

    需求: 定一个动物组件,拥有种族类型属性type,动物数组属性kinds,在Web页面上展示type标题和kinds个数。

    1、传入正确的数据,动物数组个数显示正常: 

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script src="react/react.js"></script>
        <script src="react/react-dom.js"></script>
        <script src="react/browser.min.js"></script>
    </head>
    <body>
        <div id="container"></div>
        <script type="text/babel">
    
            const AnimalComponent = React.createClass({
                render(){
                    const {type, kinds} = this.props
                    const divStyle = {
                        400,
                        height:100,
                        backgroundColor:"#DAE",
                        color:"red",
                        textAlign:"center"
                    }
                    return (
                        <div className="animal" style={divStyle}>
                            <h1>{type}</h1>
                            <p>
                                <span>{kinds.length} kinds animals</span>
                            </p>
                        </div>
                    )
                }
            })
    
            const kinds = ["cat","dog","pig","Cattle","sheep"]
            ReactDOM.render(
                <AnimalComponent type="Breastfeeding animation" kinds={kinds} />,
                document.getElementById("container")
            )
    
        </script>
    </body>
    </html>

    2、如果将数组kinds当做字符串传入,Web页面虽然没有挂掉,但是动物数组个数却显示异常,如果开发者检查不仔细,那就是线上的bug了:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script src="react/react.js"></script>
        <script src="react/react-dom.js"></script>
        <script src="react/browser.min.js"></script>
    </head>
    <body>
        <div id="container"></div>
        <script type="text/babel">
    
    
            const AnimalComponent = React.createClass({
                render(){
                    const {type, kinds} = this.props
                    const divStyle = {
                        400,
                        height:100,
                        backgroundColor:"#DAE",
                        color:"red",
                        textAlign:"center"
                    }
                    return (
                        <div className="animal" style={divStyle}>
                            <h1>{type}</h1>
                            <p>
                                <span>{kinds.length} kinds animals</span>
                            </p>
                        </div>
                    )
                }
            })
    
            const kinds = "this is a cat"
            ReactDOM.render(
                <AnimalComponent type="Breastfeeding animation" kinds={kinds} />,
                document.getElementById("container")
            )
    
    
        </script>
    </body>
    </html>
    View Code

    3、如果此时添加属性验证器,再将数组kinds当做字符串传入,Web页面没有挂掉的同时,控制台还会爆出警告,可以及时发现数据问题:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script src="react/react.js"></script>
        <script src="react/react-dom.js"></script>
        <script src="react/browser.min.js"></script>
    </head>
    <body>
        <div id="container"></div>
        <script type="text/babel">
    
    
            const AnimalComponent = React.createClass({
    
                propTypes: {
                    type: React.PropTypes.string,
                    kinds: React.PropTypes.array
                },
    
                render(){
                    const {type, kinds} = this.props
                    const divStyle = {
                        400,
                        height:100,
                        backgroundColor:"#DAE",
                        color:"red",
                        textAlign:"center"
                    }
                    return (
                        <div className="animal" style={divStyle}>
                            <h1>{type}</h1>
                            <p>
                                <span>{kinds.length} kinds animals</span>
                            </p>
                        </div>
                    )
                }
            })
    
            const kinds = "this is a cat"
            ReactDOM.render(
                <AnimalComponent type="Breastfeeding animation" kinds={kinds} />,
                document.getElementById("container")
            )
    
    
        </script>
    </body>
    </html>
    View Code

    4、如果此时添加属性验证器的同时,还限制属性是isRequried,那么在渲染组件时,不传递参数,Web页面直接会挂掉成空白页了,当然可以提前设置默认参数避免这种问题:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script src="react/react.js"></script>
        <script src="react/react-dom.js"></script>
        <script src="react/browser.min.js"></script>
    </head>
    <body>
        <div id="container"></div>
        <script type="text/babel">
    
    
            const AnimalComponent = React.createClass({
    
                propTypes: {
                    type: React.PropTypes.string.isRequired,
                    kinds: React.PropTypes.array.isRequired
                },
    
                render(){
                    const {type, kinds} = this.props
                    const divStyle = {
                        400,
                        height:100,
                        backgroundColor:"#DAE",
                        color:"red",
                        textAlign:"center"
                    }
                    return (
                        <div className="animal" style={divStyle}>
                            <h1>{type}</h1>
                            <p>
                                <span>{kinds.length} kinds animals</span>
                            </p>
                        </div>
                    )
                }
            })
    
            ReactDOM.render(
                <AnimalComponent/>,
                document.getElementById("container")
            )
    
    
        </script>
    </body>
    </html>
    View Code

    5、如果此时添加自定义的属性验证器,再将数组kinds当做字符串传入,Web页面没有挂掉的同时,控制台还可以弹出自定义的警告信息:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script src="react/react.js"></script>
        <script src="react/react-dom.js"></script>
        <script src="react/browser.min.js"></script>
    </head>
    <body>
        <div id="container"></div>
        <script type="text/babel">
    
            const AnimalComponent = React.createClass({
    
                propTypes: {
                    type: React.PropTypes.string,
                    kinds: (props, propName) =>
                            (typeof props[propName] === 'string') ? new Error(`${propName} is not array`) : null
                },
    
                render(){
                    const {type, kinds} = this.props
                    const divStyle = {
                        400,
                        height:100,
                        backgroundColor:"#DAE",
                        color:"red",
                        textAlign:"center"
                    }
                    return (
                        <div className="animal" style={divStyle}>
                            <h1>{type}</h1>
                            <p>
                                <span>{kinds.length} kinds animals</span>
                            </p>
                        </div>
                    )
                }
            })
    
            const  kinds = "this is a cat"
            ReactDOM.render(
                <AnimalComponent type="Breastfeeding animation" kinds={kinds} />,
                document.getElementById("container")
            )
    
    
        </script>
    </body>
    </html>
    View Code

  • 相关阅读:
    redis持久化的几种方式
    Spring Cloud基础教程
    微服务实践三: 服务编排
    分库分表的几种常见玩法及如何解决跨库查询等问题
    Spring Cloud微服务开发笔记5——Ribbon负载均衡策略规则定制
    第1章 Python基础-Python介绍&循环语句 练习题&作业
    MySQL中 optimize table '表名'的作用
    Python3 命令行参数
    Python enumerate() 函数
    Python rpartition() 方法
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/11988943.html
Copyright © 2020-2023  润新知