一、简介

在开发中,属性变量类型的验证,几乎是任何语言都必须关注的问题,因为如果传入的数据类型不对,轻者程序运行仅仅是给出警告⚠️,严重的会直接导致程序中断,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 = {
width: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 = {
width: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>

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 = {
width: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>

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 = {
width: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>

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 = {
width: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>

React: React的属性验证机制的更多相关文章

  1. React 学习(二) ---- props验证与默认属性

    在上一节中, 我们提到了props, 组件之间数据的传递使用props. 我们调用组件时可以设置props, 组件内部通过props获取. 为了props 使用更加友好, React 提供了简单的验证 ...

  2. React库protypes属性

    Prop 验证 随着应用不断变大,保证组件被正确使用变得非常有用.为此我们引入propTypes.React.PropTypes 提供很多验证器 (validator) 来验证传入数据的有效性.当向 ...

  3. 【React系列】Props 验证

    Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效.当向 props 传入无效 ...

  4. React组件的防呆机制(propTypes)

    Prop验证 随着应用不断变大,为了保证组件被正确使用变得越来越重要.为此我们引入propsTypes.React.PropTypes提供很多验证器(valodator)来验证传入的数据的有效性.当向 ...

  5. react第九单元(propTypes验证)

    第九单元(propTypes验证) #课程目标 理解类型验证的必要性 灵活掌握类型验证的使用 #知识点 在给react组件传属性的的时候,我们可以定义属性的类型,此时我们需要下载prop-types这 ...

  6. 从零开始学前端,React框架背后的核心机制和原理JSX

    什么是React React是起源于Facebook的一个前端框架,用于构建用户界面的JavaScript库,Facebook用来探索一种更加高效优雅的Javascript MVC框架来架设Insta ...

  7. HTML5 number类型文本框step属性的验证机制——张鑫旭

    我在下一盘很大的棋,本文只是其中的一个棋子. 需要提前知道的: 目前而言,对step雄起的浏览器为IE10+, Chrome以及Opera浏览器. 需要预先知道number类型input的一些基本知识 ...

  8. React Native声明属性和属性确认

    属性声明 因为用React Native创建的自定义组件可以复用, 我们开发过程中可能一个项目组有多个人同时开发,其他同事可能会用到我们自定义的组件, 但是他们使用的时候很容易忘记使用某些属性,这时候 ...

  9. react的三大属性

    react的三大属性 state props  refs props 来自外部属性 states 来自内部状态 refs 用于表示组件内某个元素 state基础(最重要的属性) state是组件对象最 ...

随机推荐

  1. 修改so库中的依赖名

    修改so库中的依赖名 在ArchLinuxArm上有一些针对aarch64, arm, armeabi-v7a等Android常用架构的so库可以下载,有时候可以省去很多编译时间,且都是编译optim ...

  2. 表单生成器(Form Builder)之伪造表单数据番外篇——随机车辆牌照

    前几天记录了一下表单生成器(Form Builder)之表单数据存储结构mongodb篇,之后便想着伪造一些数据.为什么要伪造数据呢?说来惭愧,因为拖拉拽设计表单以及表单对应的列表的PC端和移动端该显 ...

  3. 初级模拟电路:4-1 BJT交流分析概述

    回到目录 BJT晶体管的交流分析(也叫小信号分析)是模拟电路中的一个难点,也可以说是模电中的一个分水岭.如果你能够把BJT交流分析的原理全都搞懂,那之后的学习就是一马平川了.后面的大部分内容,诸如:场 ...

  4. [Linux] 多进程网络编程监听一个端口

    SO_REUSEPORT支持多个进程或者线程绑定到同一端口 每个进程可以自己创建socket.bind.listen.accept相同的地址和端口,各自是独立平等的.让多进程监听同一个端口,各个进程中 ...

  5. s3c2440裸机-代码重定位(2.编程实现代码重定位)

    代码重定位(2.编程实现代码重定位) 1.引入链接脚本 我们上一节讲述了为什么要重定位代码,那么怎么去重定位代码呢? 上一节我们发现"arm-linux-ld -Ttext 0 -Tdata ...

  6. ASCII码表收藏

    ASCII码表 ASCII码值 ESC键 VK_ESCAPE (27)回车键: VK_RETURN (13)TAB键: VK_TAB (9)Caps Lock键: VK_CAPITAL (20)Shi ...

  7. 【机器学习基础】交叉熵(cross entropy)损失函数是凸函数吗?

    之所以会有这个问题,是因为在学习 logistic regression 时,<统计机器学习>一书说它的负对数似然函数是凸函数,而 logistic regression 的负对数似然函数 ...

  8. 原生js放大镜效果

    效果: 1.  鼠标放上去会有半透明遮罩.右边会有大图片局部图 2.  鼠标移动时右边的大图片也会局部移动 放大镜的关键原理: 鼠标在小图片上移动时,通过捕捉鼠标在小图片上的位置,定位大图片的相应位置 ...

  9. LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees

    LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees 题目: 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两 ...

  10. chrome 插件备份