React v15.5 起,React.PropTypes 已移入另一个包中。请使用 prop-types

PropTypes文档
https://react.docschina.org/docs/typechecking-with-proptypes.html
React 18 文档 https://react.dev/reference/react/Component
19个属性,默认导出 PropTypes

  1. [
  2. "PropTypes",
  3. "any","array","arrayOf",
  4. "bool","checkPropTypes","element",
  5. "exact","func","instanceOf",
  6. "node","number","object",
  7. "objectOf","oneOf","oneOfType",
  8. "shape","string","symbol"
  9. ]

prop-types 与 ts的区别

相同点: React 应用中进行类型检查的工具
不同点:

  1. PropTypes 在运行时进行类型检查,TypeScript 是在编译时进行类型检查
  2. PropTypes 可以在 JavaScript 代码中使用,TypeScript 必须作为编程语言添加到项目中
  3. PropTypes有默认值,TypeScript 只能规定变量类型,不能直接生成代码,所以也不能设置默认值
  4. TypeScript 提供了更强大的类型检查和自动补全功能,在编写代码时提供更好的开发体验和代码质量保障
    1. PropTypes 更加轻量级,适用于不需要引入编程语言的项目[

](https://react.docschina.org/docs/typechecking-with-proptypes.html)

基础类型验证

PropTypes.object

  • .isRequired 必填项,值不能为空
  • array 数组
  • object 对象
  • func 函数
  • bool 布尔值
  • number 数字
  • string 字符串
  • node 任何可被渲染的元素,包括数字,对象,数组,React元素
  • element React元素
  • sysbol
  • any 不为空的任意值

propTypes用来规范props必须满足的类型,如果验证不通过将会有warn提示

  1. import React from 'react'
  2. import PropTypes from 'prop-types'
  3. App.propTypes = {
  4. children: PropTypes.element.isRequired,
  5. name: PropTypes.string,
  6. onChange: PropTypes.func,
  7. // 属性可以声明为 JS 原生类型
  8. optionalArray: PropTypes.array,
  9. optionalBool: PropTypes.bool,
  10. optionalFunc: PropTypes.func,
  11. optionalNumber: PropTypes.number,
  12. optionalObject: PropTypes.object,
  13. optionalString: PropTypes.string,
  14. optionalSymbol: PropTypes.symbol,
  15. /* 任何东西都可以被渲染:numbers, strings, elements,或者是包含这些类型的数组(或者是片段)。*/
  16. optionalNode: PropTypes.node,
  17. // 一个 React 元素。
  18. optionalElement: PropTypes.element,
  19. }
  20. // 指定 props的默认值
  21. App.defaultProps = {
  22. name: 'title'
  23. };
  24. function App(props) {
  25. return (
  26. <div>
  27. {props.children}
  28. </div>
  29. )
  30. }
  31. export default App;

多种类型验证

  • shape() 特定形式的对象
  • oneOf([]) 指定的值,类似于枚举 enum
  • oneOfType([]) 指定的类型
  • arrayOf() 某种类型的数组
  • objectOf() 某种类型的对象
  • instanceOf() ```jsx import React from ‘react’; // 要使用必须先引入 import { shape, array, func, object, number, string, bool, node } from ‘prop-types’;

App.propTypes = { // style表示一个对象,有 color & fontSize两个属性 style: shage({ color: string, // color 是字符串 fontSize: number, // fontSize 是数字 }).isRequired, // data是数组,数组的每一项是数字 data: arrayOf(number), onChange: func.isRequired, };

function App() { }

export default App;

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/112859/1597231094758-dde362c0-9f80-40d6-8609-7d183b893497.png#averageHue=%23e9e8e7&height=303&id=I9adw&originHeight=606&originWidth=732&originalType=binary&ratio=1&rotation=0&showTitle=false&size=110239&status=done&style=none&title=&width=366)
  2. ```jsx
  3. PropTypes.array
  4. PropTypes.arrayOf(React.PropTypes.string) // 字符串类型的数组
  5. PropTypes.object // 对象
  6. PropTypes.objectOf(React.PropTypes.string) // 元素是字符串的对象
  7. PropTypes.func // 函数
  8. PropTypes.func.isRequired // 必传的参数
  9. PropTypes.bool.isRequired // 布尔值是必传的参数
  10. PropTypes.number // 数字
  11. PropTypes.string // 字符串
  12. PropTypes.node // 任何类型的: numbers, strings, elements 或者数组
  13. PropTypes.element // React 元素
  14. PropTypes.instanceOf(XXX) // 某种XXX类型的对象
  15. PropTypes.oneOf(['foo', 'bar']) // 其中的一个字符串
  16. PropTypes.oneOfType([
  17. React.PropTypes.string,
  18. React.PropTypes.array
  19. ]) // 其中的一种类型
  20. // 是否符合指定格式的对象
  21. PropTypes.shape({
  22. color: PropTypes.string,
  23. fontSize: PropTypes.number
  24. });
  25. PropTypes.any.isRequired // 可以是任何格式,必传的参数

node

多种类型,推荐使用 PropTypes.node

指React Node,任何可被渲染的元素,包括

  • ReactChild
  • ReactFragment
  • ReactPortal
  • 字符串 | 数字 | 布尔值 | 数组 | null | undefined
  • React.ReactNode -> Return value of a component

    A more technical explanation is that a valid React node is not the same thing as what is returned by React.createElement. Regardless of what a component ends up rendering, React.createElement always returns an object, which is the JSX.Element interface, but React.ReactNode is the set of all possible return values of a component

element

指React Element,即 React.CreateElement生成的元素,可以为以下类型

  • string
  • 组件实列,组件标签,React标签,例如 Buttom
  • JSX.Element -> Return value of React.createElement
  1. // React.CreateElement可以用 jsx语法糖表示
  2. <Button color="blue" shadowSize={2}>
  3. Click Me
  4. </Button>
  5. // 编译 jsx
  6. React.createElement(
  7. Button,
  8. {color: 'blue', shadowSize: 2},
  9. 'Click Me'
  10. )

defaultProps默认值

当父级没有传入 props 时,defaultProps 可以保证 props.value 有默认值
DefaultProps 的结果会被缓存

如果没有设置 defaultProps, ESLint校验会报错
ESLint: propType “title” is not required, but has no corresponding defaultProps declaration

class组件默认值

defaultProps 用来确保 this.props.name 在父组件没有特别指定的情况下,有一个初始值。
类型检查发生在 defaultProps 赋值之后,所以类型检查也会应用在 defaultProps 上面,
我们也需要保证所设置的默认值符合类型检查设定的类型

  1. class Parent extends React.PureCompnent {
  2. static defaultProps = {
  3. name: 'lucy'
  4. }
  5. }
  6. // 为属性指定默认值
  7. Parent.defaultProps = {
  8. name: 'lucy'
  9. }

函数组件默认值

  1. // 类型检查
  2. App.propTypes = {
  3. value: PropTypes.object.isRequired,
  4. onChange: PropTypes.func,
  5. };
  6. // 默认值, isRequired不需要设置默认值
  7. App.defaultProps = {
  8. onChange: () => {},
  9. };
  10. function App() {}
  11. export default App;

props.children

  1. App.propTypes = {
  2. children: element.isRequired
  3. }
  4. function App({children}) {
  5. return children // 有且仅有一个元素,否则会抛异常
  6. }

oneOf多种类型

oneOf([])
oneOfType([])

  1. import React from 'react'
  2. import PropTypes from 'prop-types'
  3. ListCard.propTypes = {
  4. name: PropTypes.string,
  5. onChange: PropTypes.func,
  6. // 属性也可以声明为类的一个实例,使用 JS 的 instanceof 运算符。
  7. optionalMessage: PropTypes.instanceOf(Message),
  8. // 属性声明为特定的值,类似于枚举
  9. optionalEnum: PropTypes.oneOf(['News', 'Photos']),
  10. // 一个对象可以是多种类型其中之一,多个值
  11. optionalUnion: PropTypes.oneOfType([
  12. PropTypes.string,
  13. PropTypes.number,
  14. PropTypes.instanceOf(Message)
  15. ]),
  16. // 一个某种类型的数组
  17. optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
  18. // 属性值为某种类型的对象
  19. optionalObjectOf: PropTypes.objectOf(PropTypes.number),
  20. // 一个特定形式的对象
  21. optionalObjectWithShape: PropTypes.shape({
  22. color: PropTypes.string,
  23. fontSize: PropTypes.number
  24. }),
  25. // 使用 'isRequired' 链接上述的类型设定,可以确保在没有提供 Props 的情况下显示警告。
  26. requiredFunc: PropTypes.func.isRequired,
  27. // 任何数据类型的值
  28. requiredAny: PropTypes.any.isRequired,
  29. }
  30. function ListCard(props) {
  31. return (
  32. <div>
  33. </div>
  34. )
  35. }
  36. export default ListCard

自定义PropTypes

自定义验证器。如果验证失败需要返回一个 Error 对象。
不要直接用console.warn 或者 throw 抛出异常, 因为它在oneOfType 的情况下无效

  1. App.propTypes = {
  2. customPropType(props, propName, componentName) {
  3. if (!/^[0-9]/.test(props[propName])) {
  4. return new Error('Validation failed!');
  5. }
  6. }
  7. }
  8. export default function App() {}

this.props.children 是父组件在 MyComponent 中添加的子节点
当 children 包含多个兄弟节点,而不是只有一个节点时,会打印错误告警
PropTypes.element.isRequired,可以指定只传递一个 children子元素

  1. import React from 'react'
  2. import PropTypes from 'prop-types'
  3. ListCard.propTypes = {
  4. children: PropTypes.element.isRequired
  5. // 属性也可以声明为自定义的验证器。验证失败则返回 Error 对象。不要使用 `console.warn` 或者 throw
  6. // 因为这不会在 `oneOfType` 类型的验证器中起作用
  7. customProp: function (props, propName, componentName) {
  8. if (!/matchme/.test(props[propName])) {
  9. return new Error(
  10. 'Invalid prop `' + propName + '` supplied to' +
  11. ' `' + componentName + '`. Validation failed.'
  12. );
  13. }
  14. },
  15. // 属性可以声明`arrayOf`和`objectOf`类型的验证器,如果验证失败,则需要返回Error对象。
  16. // 可以在数组或者对象的每一个元素上调用验证器。验证器的前两个参数分别是数组或者对象本身和当前元素的键值。
  17. customArrayProp: PropTypes.arrayOf(function (propValue, key, componentName, location, propFullName) {
  18. if (!/matchme/.test(propValue[key])) {
  19. return new Error(
  20. 'Invalid prop `' + propFullName + '` supplied to' +
  21. ' `' + componentName + '`. Validation failed.'
  22. );
  23. }
  24. })
  25. }
  26. function ListCard(props) {
  27. return (
  28. <div>
  29. </div>
  30. )
  31. }
  32. export default ListCard