此文章是翻译Typechecking With PropTypes这篇React(版本v16.2.0)官方文档。

Typechecking With PropTypes

注意:

React.PropTypes 从React v15.5 版本已经移入一个不同的包。请使用prop-types库替代

随着你的应用的增大, 你可以通过类型检测(typechecking)捕获许多bugs。对于一些应用,你可以使用JavaScript 扩展例如Flow或者TypeScript 去检测你的整个应用。但是即使你不使用这些,在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 导出一系列的验证器(validator)可以用来确认你收到有效的数据。在这个例子中,我们使用PropTypes.string。当一个无效的值被提供给prop,一个警告就会在JavaScript console 中显示。为了性能原因,propTypes 只在开发模式进行验证。

PropTypes

这有一个例子展示如何使用不同验证器:

  1. import PropTypes from 'prop-types';
  2. MyComponent.propTypes = {
  3. // You can declare that a prop is a specific JS primitive. By default, these
  4. // are all optional.
  5. optionalArray: PropTypes.array,
  6. optionalBool: PropTypes.bool,
  7. optionalFunc: PropTypes.func,
  8. optionalNumber: PropTypes.number,
  9. optionalObject: PropTypes.object,
  10. optionalString: PropTypes.string,
  11. optionalSymbol: PropTypes.symbol,
  12. // Anything that can be rendered: numbers, strings, elements or an array
  13. // (or fragment) containing these types.
  14. optionalNode: PropTypes.node,
  15. // A React element.
  16. optionalElement: PropTypes.element,
  17. // You can also declare that a prop is an instance of a class. This uses
  18. // JS's instanceof operator.
  19. optionalMessage: PropTypes.instanceOf(Message),
  20. // You can ensure that your prop is limited to specific values by treating
  21. // it as an enum.
  22. optionalEnum: PropTypes.oneOf(['News', 'Photos']),
  23. // An object that could be one of many types
  24. optionalUnion: PropTypes.oneOfType([
  25. PropTypes.string,
  26. PropTypes.number,
  27. PropTypes.instanceOf(Message)
  28. ]),
  29. // An array of a certain type
  30. optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
  31. // An object with property values of a certain type
  32. optionalObjectOf: PropTypes.objectOf(PropTypes.number),
  33. // An object taking on a particular shape
  34. optionalObjectWithShape: PropTypes.shape({
  35. color: PropTypes.string,
  36. fontSize: PropTypes.number
  37. }),
  38. // You can chain any of the above with `isRequired` to make sure a warning
  39. // is shown if the prop isn't provided.
  40. requiredFunc: PropTypes.func.isRequired,
  41. // A value of any data type
  42. requiredAny: PropTypes.any.isRequired,
  43. // You can also specify a custom validator. It should return an Error
  44. // object if the validation fails. Don't `console.warn` or throw, as this
  45. // won't work inside `oneOfType`.
  46. customProp: function(props, propName, componentName) {
  47. if (!/matchme/.test(props[propName])) {
  48. return new Error(
  49. 'Invalid prop `' + propName + '` supplied to' +
  50. ' `' + componentName + '`. Validation failed.'
  51. );
  52. }
  53. },
  54. // You can also supply a custom validator to `arrayOf` and `objectOf`.
  55. // It should return an Error object if the validation fails. The validator
  56. // will be called for each key in the array or object. The first two
  57. // arguments of the validator are the array or object itself, and the
  58. // current item's key.
  59. customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
  60. if (!/matchme/.test(propValue[key])) {
  61. return new Error(
  62. 'Invalid prop `' + propFullName + '` supplied to' +
  63. ' `' + componentName + '`. Validation failed.'
  64. );
  65. }
  66. })
  67. };

Requiring Single Children

使用React.PropTypes.element 你可以配置仅允许单个子节点传给组件:

  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. };

Default Prop Values

通过为你的props 配置一个特殊的defaultProps 属性来定义一个默认值:

  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('root')
  16. )

如果你正在用像transform-class-properties Babel 转换器,你也可以在React 组件类中声明defaultProps 作为静态属性。这个语法还没有最终通过,在浏览器中需要一步编译工作。更多信息,查看class fields proposal

  1. class Greeting extends React.Component {
  2. static defaultProps = {
  3. name: 'stranger'
  4. }
  5. render() {
  6. return (
  7. <div>Hello, {this.props.name}</div>
  8. )
  9. }
  10. }

这个defaultProps 将会确认这个this.props.name 有值即使它没有被父组件配置。这个propType 将在defaultProps 被解析之后进行类型检测,所以类型检测也可用在defaultProps 上。