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;
![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)
```jsx
PropTypes.array
PropTypes.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>
// 编译 jsx
React.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