React组件如何用PropTypes校验键名大小写不一致的Props?
解决React组件PropTypes兼容不同键名的问题
你之前的写法存在两个问题:一是PropTypes.shape()的键必须是明确的字符串,不能用PropTypes.oneOf()动态生成键名;二是拼写错误——正确的是PropTypes(大写T)而非Proptypes,这两点都会引发lint报错。下面提供两种可行的解决方案:
方案一:用oneOfType兼容两种结构
直接定义两种合法的对象结构,通过oneOfType允许组件接收任意一种:
import PropTypes from 'prop-types'; MyComponent.propTypes = { dataPayload: PropTypes.oneOfType([ PropTypes.shape({ payinData: PropTypes.arrayOf(PropTypes.shape({})), amount: PropTypes.number.isRequired }), PropTypes.shape({ payInData: PropTypes.arrayOf(PropTypes.shape({})), amount: PropTypes.number.isRequired }) ]).isRequired };
这种写法简单直观,适合结构不复杂的场景,但如果后续键名变体增多,会产生重复代码。
方案二:自定义校验函数(更灵活)
如果需要应对更复杂的校验逻辑或未来可能新增的键名变体,推荐使用自定义prop校验函数:
import PropTypes from 'prop-types'; MyComponent.propTypes = { dataPayload: function(props, propName, componentName) { const payload = props[propName]; // 校验是否为非空对象 if (typeof payload !== 'object' || payload === null) { return new Error(`给${componentName}传入的${propName}无效,必须是对象`); } // 校验amount必须是数字 if (typeof payload.amount !== 'number') { return new Error(`给${componentName}传入的${propName}.amount无效,必须是数字`); } // 校验必须包含payinData或payInData其中一个,且对应值为数组 const hasValidPayData = ('payinData' in payload && Array.isArray(payload.payinData)) || ('payInData' in payload && Array.isArray(payload.payInData)); if (!hasValidPayData) { return new Error(`给${componentName}传入的${propName}无效,必须包含'payinData'或'payInData'字段,且对应值为数组`); } } };
这种方式可以完全自定义校验规则,扩展性更强,适合复杂场景。
内容的提问来源于stack exchange,提问作者hane Smitter
相关产品推荐
相关产品推荐

