Typechecking With PropTypes

注意React.PropTypesReact v15.5开始迁移到不同的包中,请使用prop-types库。我们提供一个codemod脚本来自动化转换

随着应用的增长,你可以通过类型检查来捕获大量的bug。

对于一些应用来说,你可以使用如FlowTypeScript等JavaScript扩展来进行全局的应用类型检查。但是即使你不使用他们,React也有一些内置的类型检查功能。

如果需要在组件的props上进行类型检查,可以通过赋值特殊的propTypes进行:

  1. import PropTypes from 'prop-types';
  2. class Greeting extends React.Component {
  3. render() {
  4. return (
  5. <h1>Hello, {this.props.name}</h1>
  6. );
  7. }
  8. }
  9. Greeting.propTypes = {
  10. name: PropTypes.string
  11. };

PropTypes导出的是一系列验证器用于验证接收到的数据是否是可用的。上述例子中,我们使用了PropTypes.string.

如果接收了一个无效的prop,JavaScript控制台(console)会出现警告。出于性能原因,仅在开发模式下检查propTypes

PropTypes

下面是一些不同的验证器的示例:

  1. import PropTypes from 'prop-types';
  2. import React,{Component} from 'react';
  3. class MyComponent extends Component{};
  4. MyComponent.propTypes = {
  5. // 声明的prop可以是一个特殊的JS基础变量,默认情况下,下面都是可选的
  6. optionalArray: PropTypes.array,
  7. optionalBool: PropTypes.bool,
  8. optionalFunc: PropTypes.func,
  9. optionalNumber: PropTypes.number,
  10. optionalObject: PropTypes.object,
  11. optionalString: PropTypes.string,
  12. optionalSymbol: PropTypes.symbol,
  13. // 下面示例能够渲染任何元素: numbers, strings, elements ,array, fragment
  14. optionalNode: PropTypes.node,
  15. // 需要是 React 元素
  16. optionalElement: PropTypes.element,
  17. // 可以声明 prop 是某个类的示例
  18. optionalMessage: PropTypes.instanceOf(Message),
  19. // 可以声明 prop 在某个 enum 中的一个
  20. optionalEnum: PropTypes.oneOf(['News', 'Photos']),
  21. // 用来验证prop对象中的每一个属性
  22. optionalUnion: PropTypes.oneOfType([
  23. PropTypes.string,
  24. PropTypes.number,
  25. PropTypes.instanceOf(Message)
  26. ]),
  27. // 验证 prop 数组的每个子元素的类型
  28. optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
  29. // 检查 prop 对象的属性的类型
  30. optionalObjectOf: PropTypes.objectOf(PropTypes.number),
  31. // 用来检查 prop 对象的每个属性的类型
  32. optionalObjectWithShape: PropTypes.shape({
  33. color: PropTypes.string,
  34. fontSize: PropTypes.number
  35. }),
  36. // 检查 prop 是必须存在的(required)
  37. requiredFunc: PropTypes.func.isRequired,
  38. // 用来检查任意的数值都必须存在
  39. requiredAny: PropTypes.any.isRequired,
  40. // 你可以通过自定义验证器的方法来进行验证。
  41. // 自定义验证器应当返回一个抛出错误的Error对象。
  42. // 不要使用`console.warn`或者throw抛出错误,因为无法再 oneOfType 中使用
  43. customProp: function(props, propName, componentName) {
  44. if (!/matchme/.test(props[propName])) {
  45. return new Error(
  46. 'Invalid prop `' + propName + '` supplied to' +
  47. ' `' + componentName + '`. Validation failed.'
  48. );
  49. }
  50. },
  51. // 你也可以为'arrayOf'和'objectOf'提供自定义验证器
  52. // 如果验证失败,应该返回一个Error对象
  53. // 数组或者对象的每一个key都会被调用这个验证器。
  54. // 此验证器的前面两个参数是数组或者是对象本身以及当前遍历的index(如数组下标或对象属性key)
  55. customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
  56. if (!/matchme/.test(propValue[key])) {
  57. return new Error(
  58. 'Invalid prop `' + propFullName + '` supplied to' +
  59. ' `' + componentName + '`. Validation failed.'
  60. );
  61. }
  62. })
  63. };

检查单Children的类型

通过PropTypes.element,可以用来验证一个单children的类型:

  1. import PropTypes from 'prop-types';
  2. class MyComponent extends React.Component {
  3. render() {
  4. // This must be exactly one element or it will warn.
  5. const children = this.props.children;
  6. return (
  7. <div>
  8. {children}
  9. </div>
  10. );
  11. }
  12. }
  13. MyComponent.propTypes = {
  14. children: PropTypes.element.isRequired
  15. };

Prop 默认值

你可以通过defaultProps来为props定义默认值:

  1. class Greeting extends React.Component {
  2. render() {
  3. return (
  4. <h1>Hello, {this.props.name}</h1>
  5. );
  6. }
  7. }
  8. // Specifies the default values for props:
  9. Greeting.defaultProps = {
  10. name: 'Stranger'
  11. };
  12. // Renders "Hello, Stranger":
  13. ReactDOM.render(
  14. <Greeting />,
  15. document.getElementById('example')
  16. );

如果父组件没有指定props,则defaultProps能够指定一个默认的this.props.name.

当然,即使指定了defaultPropspropTypes的类型检查也会作用于defaultProps.