ReactJS - 属性类型



JavaScript 是一种动态类型语言。这意味着 JavaScript 不需要声明或指定变量的类型。在程序执行(运行时)期间,JavaScript 会检查分配给变量的值,然后推断变量的类型。例如,如果将变量 num 分配给 John,则推断出 num 的类型是字符串。如果将同一变量 num 赋值为 10,则推断 num 的类型为 number。


var num = 'John' // The type of `num` is string
var num = 10 	 	 // The type of `num` is number

动态类型对于脚本语言有好处,因为它可以加快开发速度。动态类型的另一面是 JavaScript 引擎在开始执行程序之前不知道变量的类型。这会阻止 JavaScript 引擎查找或识别某些错误。例如,下面提到的代码不执行并停止程序。


var num = 10
var name = 'John'
var result = num + name // throws error during runtime

React 和类型

在 React 中,每个组件都会有多个 props,每个 props 都应该被赋值给类型正确的值。类型错误的组件属性将引发意外行为。为了更好地理解这个问题,让我们创建一个新的应用程序并创建一个组件,该组件对其属性求和并显示结果。

要创建新的 React 应用程序,请执行以下命令,

create-react-app myapp

创建应用程序后,在组件文件夹 (src/components/PropTypes/Sum.js) 下创建一个新组件 Sum


import React from 'react'
class Sum extends React.Component {
	 	render() {
	 	 	 return <p>The sum of {this.props.num1} and {this.props.num2}
	 	 	 is {parseInt(this.props.num1) + parseInt(this.props.num2)}</p>
	 	}
}
export default Sum

在这里,Sum 组件接受两个数字 num1 和 num2,并打印给定两个数字的求和。如果为属性提供了 number 值,则该组件将工作。但是,如果 sum 组件与字符串一起提供,则它将把 NaN 显示为两个属性的总和。

他们无法发现 num1 和 num2 属性的给定值格式不正确。让我们在根组件 (src/App.js) 中使用 Sum 组件,看看它是如何呈现的。


import Sum from "./components/PropTypes/Sum";
function App() {
	 	var num1 = 10
	 	var num2 = 200
	 	var name1 = "John"
	 	var name2 = "Peter"
	 	return (
	 	 	 <div>
	 	 	 	 	<Sum num1={num1} num2={num2} />
	 	 	 	 	<Sum num1={name1} num2={name2} />
	 	 	 </div>
	 	);
}
export default App;

PropTypes

属性类型

React 社区提供了一个特殊的包,prop-types 来解决属性类型不匹配的问题。prop-types 允许通过组件内部的自定义设置 (propTypes) 使用 type 指定组件的属性。例如,可以使用 PropTypes.number 选项指定具有数字类型的属性,如下所示。


Sum.propTypes = {
	 	num1: PropTypes.number,
	 	num2: PropTypes.number
}

一旦指定了属性的类型,那么 React 将在应用程序的开发阶段抛出警告。让我们在示例应用程序中包含 propTypes,看看它如何帮助捕获属性类型不匹配问题。

使用节点包管理器(npm)安装prop-types包,如下所示 -

npm i prop-types --save

现在,指定 Sum 组件的属性类型,如下所示 -


import React from 'react'
import PropTypes from 'prop-types'
class Sum extends React.Component {
	 	render() {
	 	 	 return <p>The sum of {this.props.num1} and {this.props.num2}
	 	 	 is {parseInt(this.props.num1) + parseInt(this.props.num2)}</p>
	 	}
}
Sum.propTypes = {
	 	num1: PropTypes.number,
	 	num2: PropTypes.number
}
export default Sum

最后,使用以下命令运行应用程序 -

npm start

在您喜欢的浏览器中打开应用程序,并通过开发人员工具打开 JavaScript 控制台。JavaScript 抛出警告,指出提供了意外类型,如下所示 -

PropTypes

propTypes 仅在开发阶段工作,以消除由于对 props 类型的额外检查而导致的应用程序性能降低。这不会影响应用程序在生产/实时设置中的性能。

可用的验证器

prop-types 提供了大量现成的验证器。它们如下 -

  • PropTypes.array
  • PropTypes.bigint
  • PropTypes.bool
  • PropTypes.func
  • PropTypes.number
  • PropTypes.object
  • PropTypes.string
  • PropTypes.symbol
  • PropTypes.node - 任何可以渲染的东西
  • PropTypes.element - React 组件
  • PropTypes.elementType - React 组件的类型
  • PropTypes.instanceOf() - 指定类的实例
  • propTypes.oneOf(['Value1', 'valueN']) - Value 和 ValueN 之一
  • PropTypes.oneOfType([]) - 示例, PropTypes.oneOfType([PropTypes.number, PropTypes.bigint])
  • PropTypes.arrayOf() - 示例,PropTypes.arrayOf(PropTypes.number)
  • PropTypes.objectOf() - 示例,PropTypes.objectOf(PropTypes.number)
  • PropTypes.func.is - 必需
  • propTypes.element.is - 必需
  • PropTypes.any.is - 必需

还可以创建自定义验证器,并使用它来验证属性的值。让我们考虑一下该组件有一个 email 属性,并且值应该是一个有效的电子邮件地址。然后,可以编写一个验证函数并将其附加到 email 属性,如下所示 -

PropTypes


Sum.propTypes = {
	 	num1: PropTypes.number,
	 	num2: PropTypes.number,
	 	email: function(myProps, myPropName, myComponentName) {
	 	 	 if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(myProps[myPropName])) {
	 	 	 	 	return new Error(
	 	 	 	 	 	 'Invalid prop value `' + myProps[myPropName] + '` supplied to' +
	 	 	 	 	 	 ' `' + myComponentName + '/' + myPropName + '`. Validation failed.'
	 	 	 	 	);
	 	 	 }
	 	}
}

这里

  • /^[^\s@]+@[^\s@]+\.[^\s@]+$/ 是一个简单的正则表达式电子邮件模式。
  • myProps 表示所有属性。
  • myPropName 表示正在验证的当前属性。
  • myComponentName 表示要验证的组件的名称。

同样,可以使用下面的函数签名创建自定义验证器并将其用于数组和对象属性


PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) { ... })