目录
前言:
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>
|