ReactJS PropTypes

2025年3月17日 | 阅读 14 分钟

React props(“properties” 的缩写)用于将数据从一个组件传递到另一个组件。如果组件接收到错误类型的 props,可能会导致应用程序中出现 bug 和意外错误。

由于 JavaScript 没有内置的类型检查解决方案,许多开发人员会使用 TypeScript 和 Flow 等扩展。然而,React 有一个名为 prop types 的内部机制用于 props 验证。

我们将整数、字符串、数组等不同类型的信息作为 props 传递给组件。我们可以创建默认 props,也可以直接将 props 作为组件的属性传递。那么,让我们回顾一下我们是如何将这些 props 传递给组件的。

我们从组件外部传递 props,并在该组件内部使用它们。但是,我们是否需要检查通过 props 在组件内部接收到的值的类型呢?

是否验证在组件内部通过 props 接收到的数据完全取决于我们自己。但对于大型应用程序来说,验证通过 props 获得的数据始终是一种好的实践。这将有助于调试,也有助于避免未来的 bug。

让我们看看如何做到这一点。

React 中的 PropTypes

在 React 15.5.0 之前,PropTypes 包含在 React 包中,但在后续版本的 React 中,您需要为项目添加依赖项。您可以使用以下命令为项目添加依赖项

我们可以使用 propType 来验证从 prop 接收到的任何数据。但在使用它之前,我们必须导入它。在 index.js 文件的顶部添加以下行

导入 propTypes 后,我们就可以开始使用它们了。与 default props 类似,propTypes 也是对象,其中键是 prop 的名称,值是它们的类型。

以下语法显示了如何使用 **propTypes**

在上述语法中,componentClassName 是组件类的名称;Any other type 是我们可以作为 prop 传递的任何类型。

对于不符合 propTypes 指定的数据类型验证的 props,控制台中将出现一个警告。让我们看一个完整的程序,它使用 proptypes 进行验证,以便更好地理解。

Javascript

输出

ReactJS PropTypes

您可以在上面的程序中看到,我们正在将名为 NumberProp 的 prop 作为字符串传递,但将其验证为数字。您可以访问 ReactJS 官方文档以查看 prop 可以接受的所有有效类型。

尽管如此,一切都完美地渲染在浏览器上,但我们的浏览器控制台中有一个警告消息。此消息告诉我们,名为 NumberProp 的 prop 预计包含数值,但实际上传递了一个字符串值。

React props 有效吗?

当您调用该组件时,React props 允许您发送数据——包括数字、字符串、函数、对象、数组等。如果您有多个组件,您可以将数据从一个组件传递到另一个组件。

要将 props 传递给组件,您会在调用组件时添加它们,就像调用常规 JavaScript 函数时传递参数一样。

为什么要在 React 中验证 props?

在开发 React 应用程序时,您可能需要结构化和定义 prop 以避免 bug 和错误。就像函数可以有必需的参数一样,React 组件可以要求 prop 必须定义。否则,它将无法正确渲染。

如果您忘记将必需的 prop 传递给需要的组件,可能会导致您的应用程序行为异常。

考虑以下代码。

在上面的代码片段中,名为 PercentageStat 的组件需要三个 props 才能正确渲染:label、score 和 total。如果未提供 Score 和 Total props,则会设置默认值。App 组件渲染四次百分比统计,每次使用不同的 props。

以下是应用程序的外观(带有 Bootstrap 样式)

ReactJS PropTypes

请注意,根据用法,label prop 预计为字符串。同样,marks 和 total 需要是数值,因为它们用于计算百分比。此外,total 永远不应为 0,因为它用作除数。下面是另一个代码片段,显示了渲染 PercentState 组件但 props 无效的修改后的应用程序。

应用程序视图现在看起来像这样

ReactJS PropTypes

在 React 中使用 PropTypes

PropTypes 是 React 的内部机制,用于为组件添加类型检查。

React 组件使用名为 prop Types 的特殊属性来设置类型检查。

当 props 传递给 React 组件时,它们会根据 propTypes 属性中配置的类型定义进行检查。当向 prop 传递无效值时,JavaScript 控制台中会显示一个警告。

ReactJS PropTypes

如果为 React 组件设置了默认 props,则会在检查 prop types 之前先解析该值。因此,默认值也受 prop type 定义的约束。

请注意,PropTypes 类型检查发生在开发模式下,因此您可以在开发 React 应用程序时捕获 bug。出于性能原因,在生产环境中不会触发它。

在 React 中使用 prop-types 库

在 React 15.5.0 之前,PropTypes 实用程序是 React 包的一部分,它提供了几个验证器来为组件 props 配置类型定义。可以通过 React.PropTypes 访问它。

然而,在后续版本的 React 中,该实用程序已移至一个名为 prop-types 的独立包,因此您需要将其作为依赖项添加到您的项目中才能访问 proptypes 实用程序。

它可以导入到您的项目文件中,如下所示

import propType from 'prop-type';

React PropTypes 验证器

PropTypes 实用程序导出了大量的验证器,用于配置类型定义。下面我们将列出基本类型、可渲染类型、实例类型、多个类型、集合类型和必需 prop 类型可用的验证器。

基本类型

以下是基本数据类型的验证器。

  • PropTypes.any: Prop 可以是任何数据类型
  • PropTypes.bool: prop 必须是布尔值
  • PropTypes.number: prop 必须是数字
  • PropTypes.string: prop 必须是字符串
  • PropTypes.func: prop 必须是函数
  • PropTypes.array: prop 必须是数组
  • PropTypes.object: prop 必须是对象
  • PropTypes.symbol: prop 必须是符号

可渲染类型

PropTypes 还导出了以下验证器,以确保传递给 prop 的值可以由 React 提供。

  • node: prop 必须是 React 可以渲染的任何内容——数字、字符串、元素或包含这些类型的数组(或切片)
  • element: prop 必须是 React 元素。

PropTypes.element 验证器的常见用法是确保组件只有一个子项。如果组件没有子项或有多个子项,JavaScript 控制台上会显示一个警告。

实例类型

在需要 prop 是特定 JavaScript 类的实例的情况下,您可以使用 PropTypes.instanceOf 验证器。它利用了内置的 JavaScript instance of 运算符。

多种类型

PropTypes 还导出了可以允许有限数量的值或多种数据类型的 prop 的验证器。它们是:

  • oneOf: prop 被限制在一组指定的值内,将其视为枚举
  • oneOfType: prop 必须是指定类型集中的一种,其行为类似于类型的联合。

集合类型

除了 PropTypes.array 和 PropTypes.object 验证器之外,PropTypes 还提供了用于更复杂数组和对象验证的验证器。

PropTypes.arrayOf

PropTypes.arrayOf 确保 prop 是一个数组,其中所有项都匹配指定的类型。

PropTypes.objectOf

PropTypes.objectOf 确保 prop 是一个对象,其中所有属性值都匹配指定的类型。

PropTypes.shape

当需要对对象 prop 进行更详细的验证时,可以使用 PropTypes.shape。它确保 prop 是一个对象,包含一组指定的键,其值是指定的类型。

PropTypes.exact

对于严格(或精确)的对象匹配,您可以使用 PropTypes.exact,如下所示

必需类型

我们探索过的 PropTypes 验证器允许 prop 是可选的。但是,您可以将 isRequired 链接到任何 prop 验证器,以确保在未提供 prop 时显示警告。

React props 的自定义类型检查验证器。

通常,如果您为组件 props 定义一些自定义验证逻辑会很有帮助——例如,确保 prop 传递了一个有效的电子邮件地址。Prop-type 允许您定义自定义验证函数来为 props 进行类型检查。

原生自定义验证器

自定义验证函数接收三个参数

  • props,一个包含传递给组件的所有 props 的对象
  • propName,要验证的 prop 的名称
  • ComponentName,组件的名称

如果验证失败,它应该返回一个错误对象。不应抛出错误。另外,不应在自定义验证函数内部使用 console.warn。


ReactJS PropTypes

自定义验证函数也可以与 PropTypes.oneOfType 一起使用。下面是一个使用 isEmail 自定义验证函数的简单示例,该函数在前面的代码片段中给出。

组件在这两种情况下都将是有效的

自定义验证器和集合

自定义验证函数也可以与 PropTypes.arrayOf 和 PropTypes.objectOf 一起使用。以这种方式使用时,自定义验证函数将为数组或对象中的每个键调用。

然而,自定义验证函数接收五个参数而不是三个

  • propValue,数组或对象本身
  • key,迭代中当前项的键
  • ComponentName,组件名称
  • location,有效数据的所在地(通常是“prop”)
  • propFullName,要验证的当前项的完全解析的名称。它将是一个数组 [index];对于任何对象,它将是 key。

下面是 isEmail 自定义验证函数的一个修改版本,用于数组类型。

通用自定义验证器

考虑到我们对自定义验证函数的了解,让我们创建一个通用的自定义验证器,它可以作为独立验证器和与集合类型一起使用。

对 isEmail 自定义验证函数进行 sedikit 修改,使其成为一个通用的验证器,如下所示。

在 React 中验证 Percentage Stat

以下代码片段将 prop types 添加到我们在本教程开头回顾过的 **Percentage Stat** 组件。

在生产环境中验证 React 组件 props

调试 React 应用程序可能很困难,尤其是在复杂的情况下,如果您有兴趣在生产环境中监控和跟踪所有用户的 redux 状态。

ReactJS PropTypes
ReactJS PropTypes

LogRocket 就像是 Web 应用程序的 DVR,可以记录您网站上发生的一切。您不必猜测问题发生的原因,而可以在问题发生时汇总和报告应用程序的状态。

LogRocket Redux 中间件包为您的用户会话增加了额外的可见性。LogRocket 记录您 Redux 存储中的所有操作和状态。

使用 PropTypes 进行类型检查

React.PropTypes 自 React v15.5 起已移至一个单独的包。请改用 prop-type 库。

我们提供了一个 Codemod 脚本来自动化转换。

随着应用程序的增长,您可以借助类型检查来捕获许多 bug。您可以使用 Flow 或 TypeScript 等 JavaScript 扩展来测试某些应用程序,以测试您的整个应用程序。

但是,即使您不使用它们,React 也提供了一些内置的类型检查功能。要对组件的 props 进行类型检查,您可以分配特殊的 propTypes 属性

在此示例中,我们使用的是类组件,但相同的功能也可以应用于函数组件或 React 创建的组件。PropTypes 导出一系列验证器,可用于确保您收到的数据有效。

在此示例中,我们使用的是类组件,但相同的功能也可以应用于函数组件或 React 创建的组件。Memo 或 response.forwarded。

PropTypes 导出一系列验证器,可用于确保您收到的数据有效。在此示例中,我们正在使用 PropTypes.string。当为 prop 提供无效值时,JavaScript 控制台中会显示一个警告。出于性能原因,PropTypes 仅在开发模式下检查。

PropTypes

以下是一个记录各种提供验证器的示例

要求单个子项

使用 PropTypes.element,您可以指定只能将一个子项作为 children 传递给组件。

默认 Props 值

您可以通过将默认值分配给特殊的 DefaultProps 属性来定义 props 的默认值

使用 babel 转换,例如 plugin-proposal-class-properties(以前称为 plugin-transform-class-properties),您可以在 React 组件类中将默认 props 声明为静态属性。

此语法尚未最终确定,需要在浏览器中运行才能工作,需要编译步骤。有关更多信息,请参阅 Class field proposals。

defaultProps 将确保如果父组件未指定 this.props.name,则它将具有一个值。

propTypes 类型检查发生在 defaultProps 解析之后,因此类型检查也适用于 defaultProps。