Props 和 PropTypes 是在 React 组件之间传递只读属性的重要机制。

我们可以使用 React props(属性的缩写)将数据从一个组件发送到另一个组件。如果一个组件接收到错误类型的 props,它可能会导致您的应用程序出现错误和意外错误。

由于 JavaScript 没有内置的类型检查解决方案,因此许多开发人员使用TypeScript 和 Flow等扩展。然而,React 有一个用于 props 验证的内部机制,称为PropTypes。在本文中,我们将学习如何使用 React PropTypes 验证 props。

  • React 道具是如何工作的?

  • 为什么要在 React 中验证 props?

  • 在 React 中使用 PropType

  • prop-types在 React 中使用库

  • React PropTypes 验证器

  • 用于类型检查 React 道具的自定义验证器

  • PercentageStat在 React 中验证

如果您更喜欢视觉学习者,我建议您查看以下有关 React PropTypes 的视频教程:

React 道具是如何工作的?

使用 React props,您可以在调用该组件时向该组件发送数据,包括数字、字符串、函数、对象和数组。如果您有多个组件,则可以将数据从一个组件传递到另一个组件。

要在组件之间传递 props,您可以在调用组件时添加它们,就像在调用常规 JavaScript 函数时传递参数一样。

为什么要在 React 中验证 props?

在开发 React 应用程序时,您需要构建和定义您的 props 以避免错误和错误。就像一个函数可能有强制参数一样,React 组件可能需要定义一个 prop,否则,它将无法正确呈现。忘记将所需的道具传递给需要它的组件可能会导致您的应用程序出现意外行为。

考虑下面的代码:

import React from 'react';
import ReactDOM from 'react-dom';
​
function PercentageStat({ label, score = 0, total = Math.max(1, score) }) {return (<div><h6>{ label }</h6><span>{ Math.round(score / total * 100) }%</span></div>)
}
​
function App() {return (<div><h1>Male Population</h1><div><PercentageStat label="Class 1" total={360} score={203} /><PercentageStat label="Class 2" total={206} /><PercentageStat label="Class 3" score={107} /><PercentageStat label="Class 4" /></div></div>)
}
​
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

在上面的代码中,PercentageStat组件需要三个 props 才能正确渲染,label,score和total. score为和道具设置默认值total,以防它们未提供。PercentageStat在组件中被渲染四次App,每次使用不同的道具。

下图显示了带有一些额外Bootstrap样式的应用程序的外观:

根据使用情况,该label道具预计为string. 同样,score并且total必须是numeric值,因为它们用于计算percent。此外,total预计永远不会0因为它被用作除数。

下面的代码显示了一个修改后的应用程序,它PercentageStat使用无效的 props 渲染组件:

function App() {return (<div><h1>Male Population</h1><div><PercentageStat label="Class 1" total="0" score={203} /><PercentageStat label="Class 2" total={0} /><PercentageStat label="Class 3" score={f => f} /><PercentageStat label="Class 4" total={{}} score="0" /></div></div>)
}

现在,应用程序视图如下图所示:

在 React 中使用 PropType

PropTypes 是React为组件 props添加类型检查的内部机制。React 组件使用一个特殊的属性调用propTypes来设置类型检查:

/*** FUNCTIONAL COMPONENTS*/
function ReactComponent(props) {// ...implement render logic here
}
​
ReactComponent.propTypes = {// ...prop type definitions here
}
​
​
/*** CLASS COMPONENTS: METHOD 1*/
class ReactComponent extends React.Component {// ...component class body here
}
​
ReactComponent.propTypes = {// ...prop type definitions here
}
​
​
/*** CLASS COMPONENTS: METHOD 2* Using the `static` class properties syntax*/
class ReactComponent extends React.Component {// ...component class body here
​static propTypes = {// ...prop type definitions here}
}

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

如果为 React 组件设置了默认 propspropTypes ,则在对. 因此,默认值也受道具类型定义的约束。

请记住,类型检查propTypes只能在开发模式下进行,使您能够在将 React 应用程序发布到生产环境之前捕获它中的错误。

prop-types在 React 中使用库

在 React v15.5.0 之前,PropTypesReact 包中提供了一个名为的实用程序,它提供了许多验证器来配置组件道具的类型定义。您可以使用React.PropTypes.

但是,在更高版本的 React 中,此实用程序已移至名为prop-types. 要访问该PropTypes实用程序,您需要添加prop-types作为项目的依赖项:

npm install prop-types --save

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

import PropTypes from 'prop-types';

要了解有关如何使用prop-types以及它与使用React.PropTypes和所有可用验证器有何不同的更多信息,请查看官方prop-types 文档。

React PropTypes 验证器

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

基本类型

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

  • PropTypes.any: prop 可以是任何数据类型

  • PropTypes.bool: 道具应该是一个布尔值

  • PropTypes.number: 道具应该是一个数字

  • PropTypes.string: 道具应该是一个字符串

  • PropTypes.func: prop 应该是一个函数

  • PropTypes.array: prop 应该是一个数组

  • PropTypes.object:道具应该是一个对象

  • PropTypes.symbol: 道具应该是一个符号

Component.propTypes = {anyProp: PropTypes.any,booleanProp: PropTypes.bool,numberProp: PropTypes.number,stringProp: PropTypes.string,functionProp: PropTypes.func,arrayProp: PropTypes.array,objectPerop: PropTypes.object,symbolProp: PropTypes.symbol,
}

可渲染类型

PropTypes 还导出以下验证器,以确保 React 可以呈现 传递给 prop 的值。

  • PropTypes.node: prop 应该是 React 可以渲染的任何东西,比如包含这些类型的数字、字符串、元素、数组或片段

  • PropTypes.element: prop 应该是一个 React 元素

Component.propTypes = {nodeProp: PropTypes.node,elementProp: PropTypes.element
}

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

Component.propTypes = {children: PropTypes.element.isRequired
}

实例类型

如果你需要一个 prop 是一个特定 JavaScript 类的实例,你可以使用PropTypes.instanceOf验证器,它利用了底层的 JavaScriptinstanceof操作符:

Component.propTypes = {personProp: PropTypes.instanceOf(Person)
}

多种类型

PropTypes 还导出验证器,这些验证器可以允许有限的一组值或多组数据类型用于道具。


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →


  • PropTypes.oneOf: prop 仅限于一组指定的值,将其视为枚举

  • PropTypes.oneOfType: prop 应该是一组指定的类型之一,表现得像类型的联合

Component.propTypes = {
​enumProp: PropTypes.oneOf([true, false, 0, 'Unknown']),
​unionProp: PropTypes.oneOfType([PropType.bool,PropType.number,PropType.string,PropType.instanceOf(Person)])
​
}

集合类型

除了PropTypes.array和PropTypes.object验证器,PropTypes还提供了验证器,用于对数组和对象进行更精细的验证。

PropTypes.arrayOf

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

Component.propTypes = {
​peopleArrayProp: PropTypes.arrayOf(PropTypes.instanceOf(Person)),
​multipleArrayProp: PropTypes.arrayOf(PropTypes.oneOfType([PropType.number,PropType.string]))
​
}

PropTypes.objectOf

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

Component.propTypes = {
​booleanObjectProp: PropTypes.objectOf(PropTypes.bool),
​multipleObjectProp: PropTypes.objectOf(PropTypes.oneOfType([PropType.func,PropType.number,PropType.string,PropType.instanceOf(Person)]))
​
}

PropTypes.shape

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

Component.propTypes = {profileProp: PropTypes.shape({id: PropTypes.number,fullname: PropTypes.string,gender: PropTypes.oneOf(['M', 'F']),birthdate: PropTypes.instanceOf(Date),isAuthor: PropTypes.bool})
}

PropTypes.exact

对于严格或精确的对象匹配,PropTypes.exact如果组件中存在额外的属性,则会发出警告:

Component.propTypes = {subjectScoreProp: PropTypes.exact({subject: PropTypes.oneOf(['Maths', 'Arts', 'Science']),score: PropTypes.number})
}

所需类型

到目前为止,PropTypes我们探索的所有验证器都允许 prop 是可选的。但是,您可以链接isRequired到任何 prop 验证器,以确保在未提供 prop 时显示警告:

Component.propTypes = {
​requiredAnyProp: PropTypes.any.isRequired,requiredFunctionProp: PropTypes.func.isRequired,requiredSingleElementProp: PropTypes.element.isRequired,requiredPersonProp: PropTypes.instanceOf(Person).isRequired,requiredEnumProp: PropTypes.oneOf(['Read', 'Write']).isRequired,
​requiredShapeObjectProp: PropTypes.shape({title: PropTypes.string.isRequired,date: PropTypes.instanceOf(Date).isRequired,isRecent: PropTypes.bool}).isRequired
​
}

用于类型检查 React 道具的自定义验证器

通常,您需要为组件 props 定义一些自定义验证逻辑,例如,以确保向 props 传递有效的电子邮件地址。笔趣阁会员版App,完美爆破无需注册登录,看遍全网几乎99%小说和漫画!prop-types允许您定义可用于类型检查道具的自定义验证函数。

基本的自定义验证器

自定义验证函数接受三个参数:

  • props: 包含传递给组件的所有道具的对象

  • propName: 要验证的道具的名称

  • componentName: 组件的名称

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

const isEmail = function(props, propName, componentName) {const regex = /^((([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,})))?$/;
​if (!regex.test(props[propName])) {return new Error(`Invalid prop `${propName}` passed to `${componentName}`. Expected a valid email address.`);}
}
​
Component.propTypes = {email: isEmail,fullname: PropTypes.string,date: PropTypes.instanceOf(Date)
}

您还可以将自定义验证函数与PropTypes.oneOfType. 下面的示例使用isEmail前面代码片段中的自定义验证函数:

Component.propTypes = {email: PropTypes.oneOfType([isEmail,PropTypes.shape({address: isEmail})])
}

该组件在以下两种情况下都有效:

<Component email="glad@me.com" />
<Component email={{ address: 'glad@me.com' }} />

自定义验证器和集合

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

自定义验证函数采用五个参数而不是三个参数:

  • propValue: 数组或对象本身

  • key: 迭代中当前item的key

  • componentName: 组件的名称

  • location: 验证数据的位置,通常prop

  • propFullName:正在验证的当前项目的完全解析名称。对于数组,这将是array[index]; 对于一个对象,它将是object.key

下面是isEmail用于集合类型的自定义验证函数的修改版本:

const isEmail = function(propValue, key, componentName, location, propFullName) {const regex = /^((([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,})))?$/;
​if (!regex.test(propValue[key])) {return new Error(`Invalid prop `${propFullName}` passed to `${componentName}`. Expected a valid email address.`);}
}
​
Component.propTypes = {emails: PropTypes.arrayOf(isEmail)
}

通用的自定义验证器

考虑到我们对自定义验证函数的了解,让我们继续创建通用的自定义验证器,我们可以将其用作独立验证器以及集合类型。

我们可以使isEmail自定义验证函数成为一个通用的验证器,只需稍作修改。我们将添加一个返回或的prop变量。有了这个,我们的自定义验证器既可以单独使用,也可以与集合一起使用:propFullName``key

const isEmail = function(propValue, key, componentName, location, propFullName) {// Get the resolved prop name based on the validator usageconst prop = (location && propFullName) ? propFullName : key;
​const regex = /^((([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,})))?$/;
​if (!regex.test(propValue[key])) {return new Error(`Invalid prop `${prop}` passed to `${componentName}`. Expected a valid email address.`);}
}
​
Component.propTypes = {email: PropTypes.oneOfType([isEmail,PropTypes.shape({address: isEmail})]),emails: PropTypes.arrayOf(isEmail)
}

PercentageStat在 React 中验证

以下代码片段将 prop 类型添加到PercentageStat我们在本教程开始时查看的组件中:

import React from 'react';
import PropTypes from 'prop-types';
​
// The PercentageStat component
function PercentageStat({ label, score = 0, total = Math.max(1, score) }) {return (<div><h6>{ label }</h6><span>{ Math.round(score / total * 100) }%</span></div>)
}
​
// Checks if a value is numeric
// Either a finite number or a numeric string
function isNumeric(value) {const regex = /^(\+|-)?((\d*\.?\d+)|(\d+\.?\d*))$/;return Number.isFinite(value) || ((typeof value === "string") && regex.test(value));
}
​
​
// Checks if value is non-zero
// Value is first converted to a number
function isNonZero(value) {return +value !== 0;
}
​
​
// Takes test functions as arguments and returns a custom validation function.
// Each function passed in as argument is expected to take a value argument
// expected to accept a value and return a Boolean if it passes the validation.
// All tests must pass for the custom validator to be marked as passed.
function validatedType(...validators) {return function(props, propName, componentName) {
​const value = props[propName];
​const valid = validators.every(validator => {if (typeof validator === "function") {const result = validator(value);return (typeof result === "boolean") && result;}
​return false;});
​if (!valid) {return new Error(`Invalid prop \`${propName}\` passed to \`${componentName}\`. Validation failed.`);}
​}
}
​
// Set the propTypes for the component
PercentageStat.propTypes = {label: PropTypes.string.isRequired,score: validatedType(isNumeric),total: validatedType(isNumeric, isNonZero)
}

结论

在本教程中,我们学习了如何改进我们的 React 组件并确保它们使用 prop 类型按预期工作。通过在我们的开发环境中使用道具类型验证我们的道具,我们可以防止错误和错误在部署后影响我们的应用程序。

如何使用验证 React 道具PropTypes相关推荐

  1. react 使用 PropTypes 进行类型检查

    目录 前言 一.安装 prop-types 插件 二.PropTypes 的规则 1.PropTypes 的一系列验证 (1).检测 JS 原生类型 (2).检测任何元素 (3).检测 react 元 ...

  2. [react] 使用PropTypes和Flow有什么区别?

    [react] 使用PropTypes和Flow有什么区别? Flow 是一个针对react项目所有 JavaScript 代码的静态类型检测器,需要单独添加依赖并手动运行 PropTypes是针对组 ...

  3. react 之 prop-types

    react 之 prop-types 原文地址 在开发过程当中,经常会用到Prop的type校验,但是React.PropTypes和React.createClass这两个功能在React 15.5 ...

  4. react使用 PropTypes 和 getDefaultProps()

    一定要写PropTypes,切莫为了省事而不写 如果一个Props不是requied,一定在getDefaultProps中设置它 React.PropTypes主要用来验证组件接收到的props是否 ...

  5. React的PropTypes和DefaultProps

    文章目录 propTypes PropTypes的验证器 基本的JS类型 任何可以被渲染的元素 react元素 某个类的实例 枚举类型 指定多个类型 指定某个类型的数组 指定类型为对象且对象的属性是特 ...

  6. react 渲染道具_关于React道具的另一篇文章

    react 渲染道具 You could say this topic has been done to death, but lately I've started using a techniqu ...

  7. react中prop-types的使用

    什么是prop-types?prop代表父组件传递过来的值,types代表类型.简单来说就是用来校验父组件传递过来值的类型 首先你需要通过在终端npm/yarn install/add prop-ty ...

  8. React 的 PropTypes

    在 React 中,prop 是从外部传递给组件的数据,可以说是组件对外的一个接口属性,它也是应该有对应的规范的,比方说: 这个组件支持哪些 prop 每个 prop 应该是怎么样的格式 而 Reac ...

  9. React基础—PropTypes类型检查

    1. PropTypes类型检查 自 React v15.5 起,React.PropTypes已移入另一个包中.请使用prop-types库代替. 这里使用的方式是手脚架方式创建的项目,即: > ...

最新文章

  1. JetBrain常用快捷键+省略输入方式
  2. 查表法生成流水号的示例.sql
  3. Protocol Buffers的应用与分析
  4. Java基础总结--1
  5. vscode 日志文件_vscode 日志文件_Visual Studio Code(VS code)介绍
  6. Tomcat架构解析之Digester
  7. Python语言程序设计基础_序列型数据和控制结构综合练习(第七周)_答案_通识教育必修课程_上海师范大学
  8. 专访吴军:“腾讯无2B基因,谷歌太平庸”,“我说错了吗?”
  9. 设计模式-工厂模式(学习)
  10. python中的统计模型库——statsmodels
  11. PHP中的符号 -、= 和 :: 详解
  12. 前端模板-2【vue部分小功能、bug处理】
  13. 2021年影响谷歌Google排名的因素有哪些?
  14. js实现文件下载并重命名
  15. mysql 查看slow query_MySQL慢查询日志(slow log)
  16. 荐9个可以帮助你的公众号
  17. 进阶面试的必看的ORM架构之 ORM简介
  18. Python字符串格式化的3种方法
  19. 晨枫U盘维护工具的ISOLINUX模式可加载磁盘映像的探索及USB-ROM引导后安装系统的相关问题
  20. 朴素贝叶斯代码(Python)

热门文章

  1. 学校带学院结尾,是我的锅吗?但就算如此,二本渣院的我还是拿到了阿里的Offer
  2. NLP自然语言处理系列-week6-Seq2Seq+Attention
  3. 《阴阳师》桃花妖在哪打
  4. #输入大圆和小圆半径,输出圆环面积
  5. Switch搭配“廉价采集卡”时,稍稍降低延迟的设置方法
  6. Linux学习之常用命令
  7. 软考高级-系统架构师-访问控制XACML与RBAC
  8. 用 50 张游戏显卡检测癌症,这是“业余”程序员?
  9. MLDEV[15] | pyspark杂记
  10. KDD Cup'99 数据熟悉和特征分析