React中静态类型校验-PropTypes学习

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/suwu150/article/details/79460222

PropTypes学习
官方网址详细说明

1.基本说明

PropTypes定义为组件类自身的属性,用以定义prop的类型。在开发模式下,当提供一个不合法的值作为prop时,控制台会出现警告;在产品模式下,为了性能考虑应忽略propTypes
Prop types 是一个在运行时使用的新特性. 我们能够通过下面的方式在我们的团队里边使用.

2.版本更新

在15.5版本之后, 代替使用 PropTypes 直接从 React 对象这种导入方式, 安装一个新的包 prop-types 并且使用如下的方式进行导入:

// After (15.5)
import React from 'react';
import PropTypes from 'prop-types';
class Component extends React.Component {
  render() {
    return <div>{this.props.text}</div>;
  }
}
Component.propTypes = {
  text: PropTypes.string.isRequired,
};

如下代码,为之前的书写方式

// Before (15.4 and below)
import React from 'react';
class Component extends React.Component {
  render() {
    return <div>{this.props.text}</div>;
  }
}
Component.propTypes = {
  text: React.PropTypes.string.isRequired,
}

由于版本不一致,一般会导致如下错误:

Unhandled JS Exception: Cannot read property 'string' of undefined

只要按照版本对应起来使用就可以了

3.具体使用

静态属性,只能通过类名.属性名指定

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

Greeting.propTypes = { // 静态属性,只能通过类名.属性名指定
  name: PropTypes.string
};

React.PropTypes输出一系列的验证器,用以确保你收到的数据是合法的。

下面是一个例子记录了不同的验证器;

MyComponent.propTypes = {
  // 可以声明prop是特定的JS基本类型
  // 默认情况下这些prop都是可选的
  optionalArray:PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // 任何可以被渲染的事物:numbers, strings, elements or an array
  // (or fragment) containing these types.
  optionalNode: PropTypes.node,

  // A React element.
  optionalElement: PropTypes.element,

  // 声明一个prop是某个类的实例,用到了JS的instanceof运算符
  optionalMessage: PropTypes.instanceOf(Message),

  // 用enum来限制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
  }),

  // 你可以用以上任何验证器链接‘isRequired’,来确保prop不为空
  requiredFunc: PropTypes.func.isRequired,

  // 不可空的任意类型
  requiredAny: PropTypes.any.isRequired,

  // 自定义验证器,如果验证失败,必须返回一个Error对象
  // 不要直接使用console.warn或者throw,这些在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对象
  // 在array或者object中,验证器对于每个key都会被调用The first two
  // 验证器的前两个arguments是array或者object自身以及当前的key值
  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.'
      );
    }
  })
};

Requiring Single Child
你可以使用React.PropTypes.element指定仅可以将单一子元素作为子节点传递给组件。

class MyComponent extends React.Component {
  render() {
    // This must be exactly one element or it will warn.
    const children = this.props.children;
    return (
      <div>
        {children}
      </div>
    );
  }
}

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

默认Prop值
通过赋值特殊的defaultProps属性,你可以为props定义默认值:

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

// Specifies the default values for props:
Greeting.defaultProps = {
  name: 'Stranger'
};

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

如果父组件没有为this.props.name传值,defaultProps会给其一个默认值。propTypes的类型检测是在defaultProps解析之后发生的,因此也会对默认属性defaultProps进行类型检测。

4.无状态组件的检查和默认设置

如下面所示,对无状态组件进行设置

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { View, Text, TextInput } from 'react-native';

const TextSegment = (props) => {
  const {
    behindStyle,
    delimiter,
    delimiterStyle,
    frontStyle,
    value,
    style,
  } = props;
  let frontValue = '';
  let behindValue = '';
  const splits = value && delimiter && value.split(delimiter);

  if (splits && splits.length) {
    frontValue = splits[0];
    behindValue = splits[1];
  }

  if (!delimiter) {
    return (
      <View style={[{ flexDirection: 'row' }, style]}>
        <Text style={frontStyle}>{value}</Text>
      </View>
    );
  }

  return (
    <View style={[{ flexDirection: 'row' }, style]}>
      <Text style={frontStyle}>{frontValue}</Text>
      <Text style={delimiterStyle}>{delimiter}</Text>
      <Text style={behindStyle}>{behindValue}</Text>
    </View>
  );
};

TextSegment.propTypes = {
  frontStyle: TextInput.propTypes.style,
  delimiterStyle: TextInput.propTypes.style,
  behindStyle: TextInput.propTypes.style,
  style: View.propTypes.style,
  delimiter: PropTypes.string,
  value: PropTypes.string,
};

TextSegment.defaultProps = {
  style: {
    alignItems: 'flex-end',
  },
  value: '',
};

export default TextSegment;

在上面代码中,通过方法名进行引用propTypesdefaultProps,其他用法和组件中使用一致。

展开阅读全文

没有更多推荐了,返回首页