- ReactJS 教程
- ReactJS - 首页
- ReactJS - 简介
- ReactJS - 路线图
- ReactJS - 安装
- ReactJS - 特性
- ReactJS - 优点与缺点
- ReactJS - 架构
- ReactJS - 创建 React 应用
- ReactJS - JSX
- ReactJS - 组件
- ReactJS - 嵌套组件
- ReactJS - 使用新创建的组件
- ReactJS - 组件集合
- ReactJS - 样式
- ReactJS - 属性 (props)
- ReactJS - 使用属性创建组件
- ReactJS - props 验证
- ReactJS - 构造函数
- ReactJS - 组件生命周期
- ReactJS - 事件管理
- ReactJS - 创建一个事件感知组件
- ReactJS - 在 Expense Manager 应用中引入事件
- ReactJS - 状态管理
- ReactJS - 状态管理 API
- ReactJS - 无状态组件
- ReactJS - 使用 React Hooks 进行状态管理
- ReactJS - 使用 React Hooks 进行组件生命周期管理
- ReactJS - 布局组件
- ReactJS - 分页
- ReactJS - Material UI
- ReactJS - Http 客户端编程
- ReactJS - 表单编程
- ReactJS - 受控组件
- ReactJS - 非受控组件
- ReactJS - Formik
- ReactJS - 条件渲染
- ReactJS - 列表
- ReactJS - Keys
- ReactJS - 路由
- ReactJS - Redux
- ReactJS - 动画
- ReactJS - Bootstrap
- ReactJS - 地图
- ReactJS - 表格
- ReactJS - 使用 Flux 管理状态
- ReactJS - 测试
- ReactJS - CLI 命令
- ReactJS - 构建和部署
- ReactJS - 示例
- Hooks
- ReactJS - Hooks 简介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定义 Hooks
- ReactJS 高级
- ReactJS - 可访问性
- ReactJS - 代码分割
- ReactJS - 上下文
- ReactJS - 错误边界
- ReactJS - 转发 Refs
- ReactJS - 碎片
- ReactJS - 高阶组件
- ReactJS - 集成其他库
- ReactJS - 优化性能
- ReactJS - Profiler API
- ReactJS - 端口
- ReactJS - 无 ES6 ECMAScript 的 React
- ReactJS - 无 JSX 的 React
- ReactJS - 调和
- ReactJS - Refs 和 DOM
- ReactJS - 渲染 Props
- ReactJS - 静态类型检查
- ReactJS - 严格模式
- ReactJS - Web Components
- 其他概念
- ReactJS - 日期选择器
- ReactJS - Helmet
- ReactJS - 内联样式
- ReactJS - PropTypes
- ReactJS - BrowserRouter
- ReactJS - DOM
- ReactJS - 走马灯
- ReactJS - 图标
- ReactJS - 表单组件
- ReactJS - 参考 API
- ReactJS 有用资源
- ReactJS - 快速指南
- ReactJS - 有用资源
- ReactJS - 讨论
ReactJS - PropTypes
JavaScript 是一种动态类型的语言。这意味着 JavaScript 不需要声明或指定变量的类型。在程序执行(运行时)期间,JavaScript 检查分配给变量的值,然后推断变量的类型。例如,如果变量 num 被赋值为 John,则它推断 num 的类型为字符串。如果同一个变量 num 被赋值为 10,则它推断 num 的类型为数字。
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 都应分配给具有正确类型的 value。具有错误类型的组件 props 将引发意外行为。为了更好地理解这个问题,让我们创建一个新的应用程序并创建一个组件 Sum,它将汇总其属性并显示结果。
要创建一个新的 React 应用,请执行以下命令:
create-react-app myapp
创建应用程序后,在组件文件夹下创建一个新的组件 Sum(src/components/PropTypes/Sum.js)
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,并打印这两个数字的总和。如果为 props 提供了数字值,则组件将工作。但是,如果 sum 组件提供了字符串,则它将显示 NaN 作为这两个属性的总和。
无法找到 num1 和 num2 props 的给定值是否格式不正确。让我们在根组件 (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) 指定组件属性的类型。例如,可以使用 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 仅在开发阶段有效,以消除由于额外检查 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.isRequired
propTypes.element.isRequired
PropTypes.any.isRequired
还可以创建自定义验证器并用于验证属性的值。假设组件有一个 email 属性,并且值应为有效的电子邮件地址。然后,可以编写一个验证函数并将其附加到 email 属性,如下所示:
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) { ... })