React:props常用验证

目录

前言:

props验证:

1. 任意值

2. 字符串类型

3. 数字类型

4. 布尔值

5. 数组

6. 对象

7. 函数

8. 只接受指定的值(oneOf)

​9. 可以是多个对象类型中的一个(oneOfType)

​10. 指定类型组成的数组(arrayOf)

​11. 指定类型的属性构成的对象(objectOf)

​12. 特定 shape 参数的对象(所传的props中可包含这个属性,允许有额外的属性) 

13. 特定 exact 参数的对象(所传的props中可包含这个属性,不允许有额外的属性) 

14. 任意的类型加上isRequired都表示该props必传

15. 自定义验证

16. element元素

17. node,可以被渲染的对象 numbers, strings, elements 或 array

结语&所有示例:

前言:

需要注意的是,在React v15.5版本之后,props的验证已经转移到了prop-types库中

如果之前写过vue项目的,在关于组件传值这块,我们一般都会为props设置它的类型,是string或者number或者object等等,还会去给它一个default默认值,如果此参数必传,会把required设置为true等等这些,其实设置这些验证的作用主要是为了更加规范数据,以此来确保我们的程序,组件可以按照预想的那样正常的执行使用,当我们传入不符合验证规则的数据时,控制台就会直接抛出错误,警告开发者,我们这么做是不对的,所以,熟练掌握这个是十分有必要的

所以,我们需要引入这个库,对于使用create-react-app创建的react项目,需要使用npm 安装prop-types库:

npm install --save prop-types

对于使用html,引入cdn js库的,我们需要这样引入

<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>

大概代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.8.1/prop-types.min.js"></script>
<script type="text/babel">
    const app = document.getElementById('app')

    class Person extends React.Component {
        render() {
            return (
                <div>
                    <ul>
                        <li>需求任你提,我改算我输</li>
                    </ul>
                </div>
            );
        }
    }

    Person.propTypes = {
        //待验证的props值
    }

    ReactDOM.render(<Person/>, app)
</script>
</html>

看看页面输出:

props验证:

1. 任意值

顾名思义,这个值是什么类型,我不管,你随便!

    Person.propTypes = {
        //待验证的props值
        id: PropTypes.any, //任意值
    }

    ReactDOM.render(<Person id={'999'}/>, app)

  

2. 字符串类型

    Person.propTypes = {
        //待验证的props值
        name: PropTypes.string,  //字符串
    }

    ReactDOM.render(<Person name={'Jay丶千珏'}/>, app)

3. 数字类型

    Person.propTypes = {
        //待验证的props值
        age: PropTypes.number, //数字
    }
    ReactDOM.render(<Person age={25}/>, app)

4. 布尔值

    Person.propTypes = {
        //待验证的props值
        isLikeApple: PropTypes.bool, //布尔值
    }
    ReactDOM.render(<Person isLikeApple={true}/>, app)

5. 数组

    Person.propTypes = {
        //待验证的props值
        hobby: PropTypes.array, //数组
    }
    ReactDOM.render(<Person hobby={['打篮球', '听音乐']}/>, app)

6. 对象

    Person.propTypes = {
        //待验证的props值
        family: PropTypes.object, //对象
    }
    ReactDOM.render(<Person family={{mom: 'mom', dad: 'dad'}}/>, app)

7. 函数

由于function在js中属于关键字,所以在react中,props类型为方法时,设置为了func

    Person.propTypes = {
        //待验证的props值
        say: PropTypes.func, //函数
    }

    function say() {
        return 'hello word!'
    }

    ReactDOM.render(<Person say={say}/>, app)

 

8. 只接受指定的值(oneOf)

我指定了sex为男或者女,如果我不传递这两个值之一

    Person.propTypes = {
        sex: PropTypes.oneOf(['男', '女'])
    }
    ReactDOM.render(<Person sex={'123'}/>, app)

9. 可以是多个对象类型中的一个(oneOfType)

这里height的值应为string或者number,但是我传递了一个true布尔值,故

    Person.propTypes = {
        height: PropTypes.oneOfType([ //身高可以是数字也可以是字符串 最后总需要拼接公分
            PropTypes.string,
            PropTypes.number
        ]),
    }
    ReactDOM.render(<Person height={true}/>, app)

10. 指定类型组成的数组(arrayOf)

这里的idol必须传递一个内部元素全部是string类型组成的数组,但是我在里面传递了一个number:999

    Person.propTypes = {
        idol: PropTypes.arrayOf(PropTypes.string),  //这里喜欢的明星偶像都必须是字符串类型的
    }
    ReactDOM.render(<Person idol={['Jay', 'Vae', 999]}/>, app)

11. 指定类型的属性构成的对象(objectOf)

各个学科的分数必须为数字,但是我却在语文的分数写成了字符串100,看控制台输出

    Person.propTypes = {
        fraction: PropTypes.objectOf(PropTypes.number), //这里各个科目的成绩必须是数字
    }
    ReactDOM.render(<Person fraction={{'yuwen': '100', 'shuxue': 100, 'yingyu': 100}}/>, app)

12. 特定 shape 参数的对象(所传的props中可包含这个属性,允许有额外的属性) 

    Person.propTypes = {
        foods: PropTypes.shape({
            lunch: PropTypes.string
        }),
    }
    ReactDOM.render(<Person foods={{lunch: '大米饭', dinner: '面条'}}/>, app)

13. 特定 exact 参数的对象(所传的props中可包含这个属性,不允许有额外的属性) 

包含name1和name2两个属性值,并不包含name3,但是我传递了name3,看看结果

    Person.propTypes = {
        game: PropTypes.exact({
            name1: PropTypes.string,
            name2: PropTypes.string
        }),
    }
    ReactDOM.render(<Person game={{name1: 'lol', name3: 'NBA2K'}}/>, app)

14. 任意的类型加上isRequired都表示该props必传

    Person.propTypes = {
        city: PropTypes.string.isRequired,
    }
    ReactDOM.render(<Person/>, app)

其实当我在ws上写这段代码的时候,编辑器已经提醒我了,表示city是必传的,但是我没传递

 

15. 自定义验证

设置了邮箱格式的正则表达式,传递的 qianjue7012 很显然不是个邮箱格式,结果:抛出我们自定义的错误

请注意:如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。

    Person.propTypes = {
        email: function (props, propName, componentName) {
            const rule = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
            if (!rule.test(props[propName])) {
                return new Error('Email format error')
            }
        }
    }
    ReactDOM.render(<Person email={'qianjue7012'}/>, app)

16. element元素

    Person.propTypes = {
        slogan: PropTypes.element
    }
    ReactDOM.render(<Person slogan={<h2 style={{display: 'inline', color: '#ff0000'}}>需求任你提,我改算我输</h2>}/>, app)

17. node,可以被渲染的对象 numbers, strings, elements 或 array

依然是这个slogan这个属性,但是我传递了一个布尔值,看看结果:

    Person.propTypes = {
        slogan: PropTypes.node
    }
    ReactDOM.render(<Person slogan={true}/>, app)

结语&所有示例:

还有一些属性,我没有写示例,比如PropTypes.instanceOf(),因为到现在我还没用过。。。应该是不常见的吧,大概也就是这么多了,最后的所有例子我放最下面了!

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
<div id="app"></div>
</body>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
    const app = document.getElementById('app')

    class Person extends React.Component {
        render() {
            const {
                id,
                name,
                age,
                hobby,
                family,
                say,
                isLikeApple,
                slogan,
                sex,
                height,
                idol,
                fraction,
                foods,
                game,
                city,
                email,
                element
            } = this.props
            console.log(this.props)
            return (
                <div>
                    <ul>
                        <li>id==>{JSON.stringify(id)}</li>
                        <li>name==>{name}</li>
                        <li>age===>{age}</li>
                        <li>hobby===>{JSON.stringify(hobby)}</li>
                        <li>family===>{JSON.stringify(family)}</li>
                        <li>say===>{say()}</li>
                        <li>isLikeApple===>{JSON.stringify(isLikeApple)}</li>
                        <li>slogan===>{slogan}</li>
                        <li>sex===>{sex}</li>
                        <li>height===>{height}公分</li>
                        <li>idol===>{JSON.stringify(idol)}</li>
                        <li>fraction===>{JSON.stringify(fraction)}</li>
                        <li>foods===>{JSON.stringify(foods)}</li>
                        <li>game===>{JSON.stringify(game)}</li>
                        <li>city===>{city}</li>
                        <li>email===>{email}</li>
                        <li>element===>{element}</li>
                    </ul>
                </div>
            );
        }
    }

    Person.propTypes = {
        id: PropTypes.any, //任意值
        name: PropTypes.string,  //字符串
        age: PropTypes.number, //数字
        hobby: PropTypes.array, //数组
        family: PropTypes.object, //对象
        say: PropTypes.func, //函数
        isLikeApple: PropTypes.bool, //布尔值
        slogan: PropTypes.node, //可以被渲染的对象 numbers, strings, elements 或 array
        sex: PropTypes.oneOf(['男', '女']), //限制 prop 只接受指定的值
        height: PropTypes.oneOfType([ //可以是多个对象类型中的一个,例如 可以是字符串也可以是数字
            PropTypes.string,
            PropTypes.number
        ]),
        idol: PropTypes.arrayOf(PropTypes.string),  //指定类型组成的数组,这里喜欢的明星偶像都必须是字符串类型的
        fraction: PropTypes.objectOf(PropTypes.number), //指定类型的属性构成的对象,这里各个科目的成绩必须是数字
        foods: PropTypes.shape({  //特定 shape 参数的对象(所传的props中必须包含这个属性,允许有额外的属性)
            lunch: PropTypes.string
        }),
        game: PropTypes.exact({  //和shape相似,不同点在于,只能包含这个属性,不允许有额外的属性
            name1: PropTypes.string
        }),
        city: PropTypes.string.isRequired,  //任意的类型加上isRequired都表示该props必传
        email: function (props, propName, componentName) {
            const rule = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
            if (!rule.test(props[propName])) {
                return new Error('Email format error')
            }
        },
        element: PropTypes.element //element元素
    }
    ReactDOM.render(
        <Person
            id={'999'}
            name='千珏'
            age={25}
            hobby={['打篮球', '听音乐']}
            family={{mom: 'mom', dad: 'dad'}}
            say={say}
            isLikeApple
            slogan={<h2 style={{display: 'inline', color: '#ff0000'}}>需求任你提,我改算我输</h2>}
            sex='男'
            height={180}
            idol={['胡歌', 'Jay', 'Vae']}
            fraction={{'yuwen': 100, 'shuxue': 100, 'yingyu': 100}}
            foods={{'lunch': '大米饭', 'dinner': '面条'}}
            game={{name1: 'lol'}} //{name1: 'lol', name2: 'nba2k'}:error
            city='郑州'
            email={'qianjue7012@163.com'}
            element={<h2 style={{display: 'inline', color: '#0ad278', fontSize: '50px'}}>需求任你提,我改算我输</h2>}
        />, app)

    function say() {
        return 'hello word!'
    }
</script>
</html>
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay丶萧邦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值