react 使用 PropTypes 进行类型检查

目录

前言

一、安装 prop-types 插件

二、PropTypes 的规则

1、PropTypes 的一系列验证

(1)、检测 JS 原生类型

(2)、检测任何元素

(3)、检测 react 元素及其类型——element / elementType

(4)、arrayOf 实现数组的多重嵌套检测(元素类型只能相同)

(5)、objectOf 实现对象多重嵌套检测(元素类型只能相同)

(6)、instanceOf 检测 prop 是不是指定类的 prop

(7)、oneOf 明确值检测通过

(8)、oneOfType 多种类型检测通过

(9)、shape 检测不同对象的不同属性的不同数据类型

(10)、exact 检测是否有指定的额外属性存在

2、isRequired 设置必须数据

3、defaultProps 设置 Prop 默认值

4、react 官方给出的使用文件

三、自定义函数抛出 PropTypes 验证异常时的信息

四、PropTypes 的使用

1、ES6 中旧的使用方式

2、ES7 新的使用方式(推荐)

(1)、class 组件中使用 PropTypes 进行类型检查

(2)、函数组件中使用 PropTypes 进行类型检查

五、典型案例


前言

在开发过程中,往往需要对整个应用程序做类型检查。你可以使用 Flow 或 TypeScript 等 JavaScript 扩展来实现。

当然,如果你使用的是 React,也可以使用其内置的 PropTypes 进行类型检查。使用前必须先安装 prop-types 插件。

 

一、安装 prop-types 插件

npm install prop-types -S

 

二、PropTypes 的规则

1、PropTypes 的一系列验证

(1)、检测 JS 原生类型

static propTypes={
    love: PropTypes.array,
    isAdult: PropTypes.bool,
    ability: PropTypes.func,
    age: PropTypes.number,
    subjects: PropTypes.object,
    name: PropTypes.string,
    secret: PropTypes.symbol,
}

(2)、检测任何元素

static propTypes={
    str: PropTypes.node,
}

(3)、检测 react 元素及其类型——element / elementType

/** 假设有一个自定义的 react 组件叫做 MyComponent。 **/
// 一个 React 元素
static propTypes={
    MyComponent: PropTypes.element,
}

// 一个 React 元素类型
static propTypes={
    MyComponent: PropTypes.elementType,
}

限制单个元素:通过 PropTypes.element.isRequired 来确保传递给组件的 children 中只包含一个元素。

import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  render() {
    // 这必须只有一个元素,否则控制台会打印警告。
    const children = this.props.children;
    return (
      <div>
        {children}
      </div>
    );
  }
}

MyComponent.propTypes = {
  children: PropTypes.element.isRequired
};

(4)、arrayOf 实现数组的多重嵌套检测(元素类型只能相同)

  // 可以指定一个数组由某一类型的元素组成
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

(5)、objectOf 实现对象多重嵌套检测(元素类型只能相同)

  // 可以指定一个对象由某一类型的值组成
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

(6)、instanceOf 检测 prop 是不是指定类的 prop

// 使用 instanceof 操作符声明 prop 为指定类的实例
// 假设指定的类为 Message
optionalMessage: PropTypes.instanceOf(Message),

(7)、oneOf 明确值检测通过

// 为 prop 指定特定的值
optionalEnum: PropTypes.oneOf(['News', 'Photos']),

(8)、oneOfType 多种类型检测通过

// 一个对象可以是几种类型中的任意一个类型
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

(9)、shape 检测不同对象的不同属性的不同数据类型

弥补了 arrayOf 和 objectOf 的不足,可用于检测 元素多类型(元素类型不同) 的对象或数组。

// 可以指定一个对象由特定的类型值组成
static propTypes = {
    object: PropTypes.shape({
        name: PropTypes.string,
        age: PropTypes.number
    })
}

(10)、exact 检测是否有指定的额外属性存在

  // 具有额外属性警告的对象
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),

2、isRequired 设置必须数据

// 你可以在任何 PropTypes 属性后面加上 `isRequired` ,确保
  // 这个 prop 没有被提供时,会打印警告信息。
  requiredFunc: PropTypes.func.isRequired,

  // 任意类型的必需数据
  requiredAny: PropTypes.any.isRequired,

3、defaultProps 设置 Prop 默认值

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

// 指定 props 的默认值:
Greeting.defaultProps = {
  name: 'Stranger'
};

// 渲染出 "Hello, Stranger":
ReactDOM.render(
  <Greeting />,
  document.getElementById('example')
);

4、react 官方给出的使用文件

import PropTypes from 'prop-types';

MyComponent.propTypes = {
  // 你可以将属性声明为 JS 原生类型,默认情况下
  // 这些属性都是可选的。
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // 任何可被渲染的元素(包括数字、字符串、元素或数组)
  // (或 Fragment) 也包含这些类型。
  optionalNode: PropTypes.node,

  // 一个 React 元素。
  optionalElement: PropTypes.element,

  // 一个 React 元素类型(即,MyComponent)。
  optionalElementType: PropTypes.elementType,

  // 你也可以声明 prop 为类的实例,这里使用
  // JS 的 instanceof 操作符。
  optionalMessage: PropTypes.instanceOf(Message),

  // 你可以让你的 prop 只能是特定的值,指定它为
  // 枚举类型。
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),

  // 一个对象可以是几种类型中的任意一个类型
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

  // 可以指定一个数组由某一类型的元素组成
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // 可以指定一个对象由某一类型的值组成
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // 可以指定一个对象由特定的类型值组成
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),

  // An object with warnings on extra properties
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),

  // 你可以在任何 PropTypes 属性后面加上 `isRequired` ,确保
  // 这个 prop 没有被提供时,会打印警告信息。
  requiredFunc: PropTypes.func.isRequired,

  // 任意类型的必需数据
  requiredAny: PropTypes.any.isRequired,

  // 你可以指定一个自定义验证器。它在验证失败时应返回一个 Error 对象。
  // 请不要使用 `console.warn` 或抛出异常,因为这在 `oneOfType` 中不会起作用。
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },

  // 你也可以提供一个自定义的 `arrayOf` 或 `objectOf` 验证器。
  // 它应该在验证失败时返回一个 Error 对象。
  // 验证器将验证数组或对象中的每个值。验证器的前两个参数
  // 第一个是数组或对象本身
  // 第二个是他们当前的键。
  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 验证异常时的信息

语法:

Son.propTypes = {
      prop: function(props, propName, componentName){
          if(/*判断条件*/){
               return new Error(/*错误的参数*/)
           }
    }
}

比如:

/** 
 * 你可以指定一个自定义验证器。它在验证失败时应返回一个 Error 对象。
 * 请不要使用 `console.warn` 或抛出异常,因为这在 `oneOfType` 中不会起作用。
 **/
export function customProp (props, propName, componentName) {
  if (!/matchme/.test(props[propName])) {
    return new Error(
      'Invalid prop `' + propName + '` supplied to' +
      ' `' + componentName + '`. Validation failed.'
    );
  }
}

/** 
 * 你也可以提供一个自定义的 `arrayOf` 或 `objectOf` 验证器。
 * 它应该在验证失败时返回一个 Error 对象。
 * 验证器将验证数组或对象中的每个值。验证器的前两个参数:
 *  · 是数组或对象本身;
 *  · 是他们当前的键。
 **/
export function customArrayProp () {
  return 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 的使用

PropTypes 提供一系列验证器,用来确保组件接收到的数据类型是有效的。当传入的 prop 值类型不正确时,JavaScript 控制台将会显示警告。出于性能方面的考虑,PropTypes 仅在开发模式下进行检查。

1、ES6 中旧的使用方式

import { PureComponent } from 'react';
import PropTypes from 'prop-types';

class Greeting extends PureComponent {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

// 指定 props 的默认值
Greeting.defaultProps = {
  name: 'Stranger'
};

// 渲染 "Hello, Stranger":
ReactDOM.render(
  <Greeting />,
  document.getElementById('example')
);

2、ES7 新的使用方式(推荐)

ES7 中引入了创建静态变量的方式——使用 static 关键字。

(1)、class 组件中使用 PropTypes 进行类型检查

import { PureComponent } from 'react';
import PropTypes from 'prop-types';

class Greeting extends PureComponent {

  //如果没有传递该属性时的默认值
  static defaultProps = {
    name: 'stranger'
  }

  //如果传递该属性,该属性值必须为字符串
  static propTypes={
    name: PropTypes.string
  }

  render() {
    return (
      <div>Hello, {this.props.name}</div>
    )
  }
}

(2)、函数组件中使用 PropTypes 进行类型检查

import PropTypes from 'prop-types'

function HelloWorldComponent({ name }) {
  return (
    <div>Hello, {name}</div>
  )
}

HelloWorldComponent.propTypes = {
  name: PropTypes.string
}

export default HelloWorldComponent;

【拓展】

由 React.memo / React.forwardRef 创建的组件,也可以使用 PropTypes 进行类型检查。

 

五、典型案例

案例一:

import React from 'react';
import ReactDom from 'react-dom';
import propsTypes from 'prop-types';

/**
 * 可以放在类外(ES6)
 * // 类型约定
 * App.propTypes={
 *   num: propsTypes.number,
 *   title: propsTypes.string.isRequired//必传参数
 * };
 * // 默认值
 * App.defaultProps={//类属性|静态属性
 *   arr:[],
 * };
 **/

class App extends React.Component{
  
  /** 可以放在类内(ES7)**/
  // 类型约定
  static propTypes={
    num: propsTypes.number,
    title: propsTypes.string.isRequired//必传参数
  };
  // 默认值
  static defaultProps = {
    arr:[],
  };

  
  render(){
    return (
      <div>
        <h3>props类型检查{this.props.title}</h3>
        {this.props.arr}
        <hr/>
        {
          this.props.arr.map((val, index) => (
            <li key={index}>{val}</li>
          ))
        }
        <hr/>
        {this.props.num + 9}
      </div>
    )
  }
}

ReactDom.render(
  <App  title2={"qq"} num={123}/>,
  document.querySelector("#root")
);

 

本文参考资料:

https://www.npmjs.com/package/prop-types

https://cloud.tencent.com/developer/article/1684723

https://segmentfault.com/a/1190000016182458

https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html

https://zhuanlan.zhihu.com/p/35344200

https://blog.csdn.net/weixin_45271385/article/details/103038902

 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值