原文:How to Use PropTypes in React,作者:Ateev Duggal

当调试你的应用程序时,PropTypes是一个很好的第一道防线。但在详细了解PropTypes之前,我们必须先了解props的概念。

Props是只读属性,在组件之间共享,使React的单向流动具有动态性(dynamic touch)。它们主要是从父组件到子组件的共享,但反过来也可以(尽管不推荐)。

在这篇文章中,我们将讨论如何验证或检查我们所传递的props,以避免在后期进行复杂的调试。

什么是PropTypes?

PropTypes只是一种机制,确保传递的值是正确的数据类型。这确保了我们不会在应用的最后阶段收到控制台的错误,这可能不容易处理。

我不建议在自我练习的项目等短期应用中使用它们,但这完全取决于你。对于像客户这样的大型项目,使用它们往往是一个明智的选择和良好的做法。

有许多不同类型的PropTypes,它们都有自己独特的ES6类,我们可以使用。我们将在本文中讨论每一种类型。

如何使用PropTypes

在React 15.5.0发布之前,PropTypes在React包中包含的,但现在我们必须在我们的项目中添加prop-types库。

我们可以通过在终端运行以下命令来做到这一点:

npm install prop-types --save

我们可以使用PropTypes来验证从propps接收的任何数据。但在使用它之前,我们必须在我们的应用程序中导入它:

import PropTypes from 'prop-types';

它们通常在组件(component)结束后使用,以组件的名称开始,如图所示:

import React from 'react';
import { PropTypes } from "prop-types";
 
const Count = (props) => {
  return (
    <>
      .........
    </>
  )
};
 
Count.propTypes = {
  //// key is the name of the prop and
// value is the PropType
}
export default Count;

PropTypes也是具有键值对的对象,其中 (key)是prop的名称,而值(value)代表它们被定义的类型(type)或类(class)。

由于在组件上定义PropTypes并不取决于组件的实现,我们将在下面的所有例子中省略组件本身的代码。上面的代码可以简化为以下内容:

Count.propTypes = {
// Put props here
}

让我们先讨论一下有多少种PropTypes,然后再通过一个例子来理解它们。

PropTypes的基本类型

我们检查prop类型的最基本方法是检查它是否属于JavaScript中的原始类型,如布尔型、字符串、对象等。

下面是所有被认为是原始的或基本的数据类型的列表,以及我们可以用来检查props的类。

Type

Class

Example

String

PropType.string

“helllo”

Object

PropType.object

{name: “Rohit”}

Number

PropType.number

10

Boolean

PropType.bool

true/false

Function

PropType.func

const say = {console.log(“hello”)}

Symbol

PropType.symbol

Symbol(“m”)

下面是一个例子,告诉我们如何在我们的应用程序中使用这些PropTypes进行类型检查。正如我们已经讨论过的,它们被定义为具有一个键值对的对象,其中键是对象的名称,而值包含将用于类型检查的类。

Count.propTypes = {
  name: PropTypes.string,
  age: PropTypes.number,
  address: PropTypes.object,
  friends: PropTypes.array,
};

在上面的代码中,name应该是一个字符串,age是一个数字,address是一个对象,friends是一个数组。如果任何其他的值被用作相同的props值,它将在控制台显示一个错误,像这样:

NoiuFl2D3WofbIe7_CsqbNkolVLFzXyPSvvADV3LvFug2jp2oMhBXFl42Qy79e4LkGAOio5RD5rAhlUOBJEoSP3oDUuWNwxb1wCfQYdYQpWvdtDbKQQDkwt0rMSD9dlQAhXozKKC

以上控制台输出有关PropTypes的错误。

我们可以用isRequired配置上述任何一个,以确保在没有提供props的情况下显示一个警告。

Count.propTypes = {
  basicObject: PropTypes.object,
  numbers: PropTypes.objectOf(PropTypes.numbers),
  messages: PropTypes.instanceOf(Message),
  contactList: PropTypes.shape({
    name: PropTypes.string.isRequired,
    phone: PropTypes.string.isRequired,
  }),
};

集合类型

我们已经看到如何验证或检查props属于哪一类基本数据类型。但是还有很多方法可以传递和使用props,比如集合类型(collective types),如数字数组、字符串等等。那么,它们呢?

我们也可以为它们检查props。下面是数据类型可以组合和使用的各种方式。

数组类型

在这里,我们将讨论所有数组(Array)的使用情况,并举例说明,就像我们看到的基本类型一样。

Type

Class

Example

Array

PropTypes.array

[]

Array of numbers

PropTypes.arrayOf([type])

[1,2,3]

Array of string

PropTypes.oneOf([arr])

[“Red”, “blue”]

Array of objects

PropTypes.oneOfType([types])

PropTypes.string,

PropTypes.instanceOf(Title)

Count.propTypes = {
  counts: PropTypes.array,
  users: PropTypes.arrayOf(PropTypes.object),
  alarmColor: PropTypes.oneOf(['red', 'blue']),
  description: PropTypes.oneOfType([
  PropTypes.string,
  PropTypes.instanceOf(Title)
  ]),
  }

对象类型

就像数组类型(array types)一样,这里有一些集合对象类型(collective object types):

Type

Class

Example

Object

PropTypes.object

{name: “Anu”}

Number Object

PropTypes.objectOf()

{age: 25}

Object Shape

PropTypes.shape()

{name: PropTypes.string,

phone: PropTypes.string}

Instance

PropTypes.objectOf()

New message()

Count.propTypes = {
  basicObject: PropTypes.object,
  numbers: PropTypes.objectOf(PropTypes.numbers),
  messages: PropTypes.instanceOf(Message),
  contactList: PropTypes.shape({
    name: PropTypes.string,
    phone: PropTypes.string,
  }),
};

高级类型检查

除了基本的类型检查外,我们还有很多方法可以用来检查我们的props。这种方法主要关注React代码而不是数据类型。

如何检查React组件

如果你只想检查一个prop是否是React组件,你可以使用PropTypes.element。这对于确保一个组件只有一个子组件是很有用的。

Type

Class

Example

Element

PropTypes.element

<Title />

Count.propTypes = {
  displayEle: PropTypes.element,
};

如何检查React组件的名称

最后,我们可以通过使用PropTypes.elementType来检查该prop是否是React组件的名称。

Component.propTypes = {
  as: PropTypes.elementType
}
<AnotherComponent as={Component} />

自定义类型

我们也可以有一个自定义的验证器(validator)或props的类型检查。但是它需要一个错误对象,当验证失败时。

你可以对数组和对象使用这个方法,但错误对象将为数组或对象中的每个键(key)被调用。验证器的前两个参数是数组或对象本身和当前项目的键(key)。

Type

Class

Example

Custom

function(props, propName, componentName) {}

“hello”

Custom Array

PropTypes.arrayOf(function(props, propName, componentName) {})

[“hello”]

Count.propTypes = {  // normal functionn
  customProp: function (props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        "Invalid prop `" +
          propName +
          "` supplied to" +
          " `" +
          componentName +
          "`. Validation failed."
      );
    }
  },
};
Count.propTypes = { // array function
  customArrayProp: PropTypes.arrayOf(function (
    propValue,
    key,
    componentName,
    location,
    propFullName
  ) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        "Invalid prop `" +
          propFullName +
          "` supplied to" +
          " `" +
          componentName +
          "`. Validation failed."
      );
    }
  }),
};
 

默认PropTypes

有时,我们希望能够为一个prop设置一个默认值。例如,我们的父组件可能不需要传递标题。但我们仍然希望有一个标题被呈现出来。

在这种情况下,我们可以为我们的标题设置一个默认值,如果标题没有被作为一个prop从我们的父组件中传递出来,它将自动被呈现出来。

Header.defaultProp = {
  title: "GitHub Users",
};

我们可以在官方文档中了解更多这方面的信息。

举个例子

让我们通过一些简单的React代码来了解这一切是如何运作的。

我们将制作两个可重用的组件,About.jsCount.jsAbout组件是父组件,Count组件是子组件,如图所示:

9h86z3UDdPR9zlqR19PVQFJYvAq0j2r6ZobSn1cC6Ev8JAjQo_tFRJobuIQeg0sHLc8Wha8yZp3SGQGcxrxYMA-Mo_HrCsxBrPnv6TfhqS_q9Iqioku1LaRTbx69qBsx_PueJtqe

2RbGh5-GHCcP57-3GG9ysJ-9p7xFIOKRzg2Z_TzzJFObcqalPbUe_8MDe1iyckfD0rKxg6Kfcksd8V9uNx9SHV6sUr8yM37Z2NP1k7YS_e7WLIz-OXtq-jOS7DsRTjfj-C0PBPBp

如果我们把age prop的值从数字改为字符串,而不改变其类型(PropTypes),会怎么样?

import React from "react";
import Count from "./Count";
const About = () => {
  return (
    <>
      <div className="app">
        <Count name="Ateev" age="25" />
      </div>
    </>
  );
};
 
export default About;

我们将在控制台中收到一个错误:

NoiuFl2D3WofbIe7_CsqbNkolVLFzXyPSvvADV3LvFug2jp2oMhBXFl42Qy79e4LkGAOio5RD5rAhlUOBJEoSP3oDUuWNwxb1wCfQYdYQpWvdtDbKQQDkwt0rMSD9dlQAhXozKKC

它明确指出,传递的age prop的值与预期的值(PropTypes)不一致。

从上面的例子中,现在应该清楚我们如何使用PropTypes。你还可以看到,当应用程序太大,仅用传统方法无法找到错误时,它们对调试你的应用程序是多么有用。

结语

PropTypes是一种在运行时捕捉错误的好方法,可以作为你的应用程序的第一道防线。它们不像TypeScript那样类型安全,但它们更容易设置和使用。

你也可以阅读我的一些其他文章:

  1. React中的虚拟DOM是什么意思?
  2. React中的Hooks是什么?
  3. 如何在React中制作一个作品集