前言
通常,我们在项目中使用自定义组件时,需要对组件的props进行类型检测。而React提供了专门的库,可以校验组件的props类型,也可以做一些特定的限制。下面行详细介绍。
以下内容大部分来自[React官网](https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html#gatsby-focus-wrapper),根据我的开发经验进行了补充。
如何使用
项目中安装prop-types
npminstallprop-types--save
页面引入
importPropTypesfrom'prop-types';
使用
在需要加入类型校验的组件中引入prop-types,并对需要类型校验的props属性添加类型验证器。
/** * @description Switch 开关组件 */importReactfrom'react'; importPropTypesfrom'prop-types'; constSwitch= ({ props }) => { return<div>{props.children}</div>;}; Switch.propTypes= { color: PropTypes.string, // 开关颜色loading: PropTypes.bool, // 是否为加载状态}; exportdefaultSwitch;
eslint校验
如果项目中加入了eslint校验,可以设置不强制使用prop-types,将react/prop-types项设置为0即可。
module.exports= { rules: { // 不强制使用prop-types'react/prop-types': 0, }, };
propTypes提供的验证器
原生类型
可以将属性声明为 JS 原生类型,默认情况下这些属性都是可选的。
Switch.propTypes= { optionalArray: PropTypes.array, optionalBool: PropTypes.bool, optionalFunc: PropTypes.func, optionalNumber: PropTypes.number, optionalObject: PropTypes.object, optionalString: PropTypes.string, optionalSymbol: PropTypes.symbol, };
任何可被渲染的元素
包括数字、字符串、元素、数组、Fragment等。
Switch.propTypes= { optionalNode: PropTypes.node, };
一个 React 元素
React 元素,指React.CreateElement生成的元素。
可以通过 PropTypes.element 来确保传递给组件的 children 中只包含一个元素。
/** * @description Switch 开关 */importReactfrom'react'; importPropTypesfrom'prop-types'; constSwitch= ({ props }) => { // 这必须只有一个元素,否则控制台会打印警告。constchildren=props.children; return<div>{children}</div>;}; Switch.propTypes= { children: PropTypes.element, }; exportdefaultSwitch;
多种类型
一个对象可以是几种类型中的任意一个类型。
方法oneOfType接收的参数是数组,设置的不同类型用逗号分开。
Switch.propTypes= { optionalUnion: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), };
限定值
可以让 props只能是特定的值,指定它为枚举类型.
方法oneOf接收的参数是数组,设置的特定值用逗号分开。
Switch.propTypes= { optionalEnum: PropTypes.oneOf(['News', 'Photos']), };
类的实例
使用JS 的 instanceof 操作符声明 prop 为类的实例。
注:指定的类不能是自定义的React类。
// 正确代码Switch.propTypes= { optionalArray: PropTypes.instanceOf(Array), }; // 报错代码// 指定的类不能是自定义的React类,否则代码会报错:Invalid prop `optionalArray` of type `Object` supplied to `Loading`, expected instance of `Custom`.Switch.propTypes= { optionalArray: PropTypes.instanceOf(Custom), };
参数必传限制
如果想设置某项prop为必须的,可以在任何 PropTypes 属性后面加上 `isRequired`,这个 prop 没有被提供时,会打印警告信息。
Switch.propTypes= { requiredFunc: PropTypes.func.isRequired, };
任意类型
也可以设置任意类型,使用any声明任意类型。
实际开发中声明任意的意义不大,因为propTypes本身就是非必须的,声明任意和不做任何声明是一样的。但是有些情况,我们又想给某些参数设置必填校验,但是这类参数的校验类型又不想设置的特别局限,就可以把any和isRequired结合使用,这种组合校验在实际开发中也经常用到。
// 任意类型Switch.propTypes= { optionalAny: PropTypes.any, }; // 任意类型的必需数据Switch.propTypes= { requiredAny: PropTypes.any.isRequired, };
其他类型
以下几种类型我日常用到的相对较少,所以直接将React文档里的内容复制出来。如果有大佬愿意分享,欢迎留言💐
Switch.propTypes= { // 可以指定一个数组由某一类型的元素组成optionalArrayOf: PropTypes.arrayOf(PropTypes.number), // 可以指定一个对象由某一类型的值组成optionalObjectOf: PropTypes.objectOf(PropTypes.number), // 可以指定一个对象由特定的类型值组成optionalObjectWithShape: PropTypes.shape({ color: PropTypes.string, fontSize: PropTypes.number, }), // 可以指定一个对象由具有额外属性警告值组成optionalObjectWithStrictShape: PropTypes.exact({ name: PropTypes.string, quantity: PropTypes.number, }), };
默认 Prop 值
可以通过配置特定的 defaultProps 属性来定义 props 的默认值。
// 开关组件,默认字体颜色为#c9c9c9 默认是否有加载效果为不加载Switch.defaultProps= { color: '#c9c9c9', loading: false, };
结束
PropTypes在项目的频率相对较高,尤其是我们在自定义组件的时候,props添加类型校验也是非常好的编程习惯。所以我把PropTypes的知识点和日常使用的实例结合起来放到文章中,也当成自己的一遍知识点笔记,方便日后查阅。