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
["PropTypes","any","array","arrayOf","bool","checkPropTypes","element","exact","func","instanceOf","node","number","object","objectOf","oneOf","oneOfType","shape","string","symbol"]
prop-types 与 ts的区别
相同点: React 应用中进行类型检查的工具
不同点:
- PropTypes 在运行时进行类型检查,TypeScript 是在编译时进行类型检查
- PropTypes 可以在 JavaScript 代码中使用,TypeScript 必须作为编程语言添加到项目中
- PropTypes有默认值,TypeScript 只能规定变量类型,不能直接生成代码,所以也不能设置默认值
- TypeScript 提供了更强大的类型检查和自动补全功能,在编写代码时提供更好的开发体验和代码质量保障
- 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提示
import React from 'react'import PropTypes from 'prop-types'App.propTypes = {children: PropTypes.element.isRequired,name: PropTypes.string,onChange: PropTypes.func,// 属性可以声明为 JS 原生类型optionalArray: PropTypes.array,optionalBool: PropTypes.bool,optionalFunc: PropTypes.func,optionalNumber: PropTypes.number,optionalObject: PropTypes.object,optionalString: PropTypes.string,optionalSymbol: PropTypes.symbol,/* 任何东西都可以被渲染:numbers, strings, elements,或者是包含这些类型的数组(或者是片段)。*/optionalNode: PropTypes.node,// 一个 React 元素。optionalElement: PropTypes.element,}// 指定 props的默认值App.defaultProps = {name: 'title'};function App(props) {return (<div>{props.children}</div>)}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;
```jsxPropTypes.arrayPropTypes.arrayOf(React.PropTypes.string) // 字符串类型的数组PropTypes.object // 对象PropTypes.objectOf(React.PropTypes.string) // 元素是字符串的对象PropTypes.func // 函数PropTypes.func.isRequired // 必传的参数PropTypes.bool.isRequired // 布尔值是必传的参数PropTypes.number // 数字PropTypes.string // 字符串PropTypes.node // 任何类型的: numbers, strings, elements 或者数组PropTypes.element // React 元素PropTypes.instanceOf(XXX) // 某种XXX类型的对象PropTypes.oneOf(['foo', 'bar']) // 其中的一个字符串PropTypes.oneOfType([React.PropTypes.string,React.PropTypes.array]) // 其中的一种类型// 是否符合指定格式的对象PropTypes.shape({color: PropTypes.string,fontSize: PropTypes.number});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
// React.CreateElement可以用 jsx语法糖表示<Button color="blue" shadowSize={2}>Click Me</Button>// 编译 jsxReact.createElement(Button,{color: 'blue', shadowSize: 2},'Click Me')
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 上面,
我们也需要保证所设置的默认值符合类型检查设定的类型
class Parent extends React.PureCompnent {static defaultProps = {name: 'lucy'}}// 为属性指定默认值Parent.defaultProps = {name: 'lucy'}
函数组件默认值
// 类型检查App.propTypes = {value: PropTypes.object.isRequired,onChange: PropTypes.func,};// 默认值, isRequired不需要设置默认值App.defaultProps = {onChange: () => {},};function App() {}export default App;
props.children
App.propTypes = {children: element.isRequired}function App({children}) {return children // 有且仅有一个元素,否则会抛异常}
oneOf多种类型
oneOf([])
oneOfType([])
import React from 'react'import PropTypes from 'prop-types'ListCard.propTypes = {name: PropTypes.string,onChange: PropTypes.func,// 属性也可以声明为类的一个实例,使用 JS 的 instanceof 运算符。optionalMessage: PropTypes.instanceOf(Message),// 属性声明为特定的值,类似于枚举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' 链接上述的类型设定,可以确保在没有提供 Props 的情况下显示警告。requiredFunc: PropTypes.func.isRequired,// 任何数据类型的值requiredAny: PropTypes.any.isRequired,}function ListCard(props) {return (<div></div>)}export default ListCard
自定义PropTypes
自定义验证器。如果验证失败需要返回一个 Error 对象。
不要直接用console.warn 或者 throw 抛出异常, 因为它在oneOfType 的情况下无效
App.propTypes = {customPropType(props, propName, componentName) {if (!/^[0-9]/.test(props[propName])) {return new Error('Validation failed!');}}}export default function App() {}
this.props.children 是父组件在 MyComponent 中添加的子节点
当 children 包含多个兄弟节点,而不是只有一个节点时,会打印错误告警
PropTypes.element.isRequired,可以指定只传递一个 children子元素
import React from 'react'import PropTypes from 'prop-types'ListCard.propTypes = {children: PropTypes.element.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对象。// 可以在数组或者对象的每一个元素上调用验证器。验证器的前两个参数分别是数组或者对象本身和当前元素的键值。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.');}})}function ListCard(props) {return (<div></div>)}export default ListCard
