Typechecking With PropTypes

随着应用规模的提升,你可以通过类型检测捕捉更多的bug。对于部分应用,你可能需要需要使用类似于Flow或者TypeScript的JavaScript扩展来对你整个应用类型进行类型检测。但即使你不使用这些,React内置了类型检测的功能。要在组件中进行类型检测,你可以赋值propTypes属性。

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

React.PropTypes 输出了一系列的验证器,可以用来确保接收到的参数是有效的。例如,我们可以使用React.PropTypes.string语句。当给prop传递了一个不正确的值时,JavaScript控制台将会显示一条警告。出于性能的原因,propTypes仅在开发模式中检测。

React.PropTypes

下面给出不同验证器的示例:

  1. MyComponent.propTypes = {
  2. // 声明prop一个特定的基本类型,默认情况,是可选的。
  3. optionalArray: React.PropTypes.array,
  4. optionalBool: React.PropTypes.bool,
  5. optionalFunc: React.PropTypes.func,
  6. optionalNumber: React.PropTypes.number,
  7. optionalObject: React.PropTypes.object,
  8. optionalString: React.PropTypes.string,
  9. optionalSymbol: React.PropTypes.symbol,
  10. // 任何可以被渲染:numbers, strings, elements,或者是包含这些类型的数组(或者是片段)
  11. optionalNode: React.PropTypes.node,
  12. // A React element.
  13. optionalElement: React.PropTypes.element,
  14. // 声明props是一个类,使用JS的instanceof操作符
  15. optionalMessage: React.PropTypes.instanceOf(Message),
  16. // 声明prop是特定的值,类似于枚举
  17. optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
  18. // 多种类型其中之一
  19. optionalUnion: React.PropTypes.oneOfType([
  20. React.PropTypes.string,
  21. React.PropTypes.number,
  22. React.PropTypes.instanceOf(Message)
  23. ]),
  24. // 包含测定类型的数组
  25. optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
  26. // 值为特定类型的对象
  27. optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
  28. // 特定形式的对象
  29. optionalObjectWithShape: React.PropTypes.shape({
  30. color: React.PropTypes.string,
  31. fontSize: React.PropTypes.number
  32. }),
  33. // 可以为上面的声明后添加`isRequired`使得如果没有提供props会给出warning
  34. // You can chain any of the above with `isRequired` to make sure a warning
  35. // is shown if the prop isn't provided.
  36. requiredFunc: React.PropTypes.func.isRequired,
  37. // 任何值
  38. requiredAny: React.PropTypes.any.isRequired,
  39. // 可以声明自定义的验证器,如果验证失败返回Error对象。不要使用`console.warn`或者throw
  40. // 因为这不会在`oneOfType`类型的验证器中起作用。
  41. customProp: function(props, propName, componentName) {
  42. if (!/matchme/.test(props[propName])) {
  43. return new Error(
  44. 'Invalid prop `' + propName + '` supplied to' +
  45. ' `' + componentName + '`. Validation failed.'
  46. );
  47. }
  48. },
  49. // 也可以声明`arrayOf`和`objectOf`类型的验证器,如果验证失败需要返回Error对象。
  50. // 会在数组或者对象的每一个元素上调用验证器。验证器的前两个参数分别是数组或者对象本身,
  51. // 以及当前元素的键值。
  52. customArrayProp: React.PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
  53. if (!/matchme/.test(propValue[key])) {
  54. return new Error(
  55. 'Invalid prop `' + propFullName + '` supplied to' +
  56. ' `' + componentName + '`. Validation failed.'
  57. );
  58. }
  59. })
  60. };

Requiring Single Child

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

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

默认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. );

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