Reactjs 使用动态关键点检查对象的属性类型

Reactjs 使用动态关键点检查对象的属性类型,reactjs,Reactjs,React有很多使用PropTypes检查道具值的方法。我常用的一种方法是React.PropTypes.shape({…})。但是,我最近遇到了一种情况,我有一个对象,其中包含动态键/值。我知道每个键都应该是一个字符串(以已知格式),每个值都应该是一个int。即使使用自定义道具验证函数,它仍然假设您知道道具的键。如何使用PropTypes检查对象/形状的键和值是否正确 ... someArray: React.PropTypes.arrayOf(React.PropTypes.shape({

React有很多使用PropTypes检查道具值的方法。我常用的一种方法是
React.PropTypes.shape({…})
。但是,我最近遇到了一种情况,我有一个对象,其中包含动态键/值。我知道每个键都应该是一个字符串(以已知格式),每个值都应该是一个int。即使使用自定义道具验证函数,它仍然假设您知道道具的键。如何使用PropTypes检查对象/形状的键和值是否正确

...
someArray: React.PropTypes.arrayOf(React.PropTypes.shape({
  // How to specify a dynamic string key? Keys are a date/datetime string
  <dynamicStringKey>: React.PropTypes.number
}))
...
。。。
someArray:React.PropTypes.arrayOf(React.PropTypes.shape({
//如何指定动态字符串键?键是日期/日期时间字符串
:React.PropTypes.number
}))
...

因此,我想至少检查每个键的值是否是一个数字。理想情况下,我还希望能够检查密钥本身是否为正确格式的字符串。

您可以通过传递函数来创建自己的验证器

请参见
customProp

我相信您可以执行类似于
React.PropTypes.arrayOf(customValidator)
的操作

以下是您正在寻找的验证器:

function objectWithNumericKeys(obj) {
  if (Object.keys(obj).some(key => isNaN(key)))
     return new Error('Validation failed!');
}
注意:这个答案是在2015年写的,当时React的当前版本是0.14.3。它可能适用于也可能不适用于您今天使用的React版本

这是一个有趣的问题。从你的问题看来,你好像 在的文档中阅读有关自定义类型检查器的信息。 为了子孙后代,我将在这里复制:

//您还可以指定自定义验证器。它应该返回一个错误
//对象,如果验证失败。不要像这样“安慰、警告”或“扔”
//在“oneOfType”中不起作用。
customProp:函数(props、propName、componentName){
if(!/matchme/.test(props[propName])){
返回新错误('验证失败!');
}
}
在实现类型检查器时,我更喜欢使用React的内置类型 尽可能多地跳棋。您要检查这些值是否正确 数字,所以我们应该使用
PropTypes.number
,对吗?会的 如果我们可以做
PropTypes.number('nota number!')
并获得 这是一个适当的错误,但不幸的是,它有点复杂 比那还多。第一站是了解

类型检查器的工作原理 以下是类型检查器的函数签名:

函数(props,propName,componentName,location,propFullName)=>null |错误
如您所见,所有的道具都作为第一个参数传递,并且 正在测试的道具的名称作为第二个道具传递。最后 三个参数用于打印有用的错误消息,它们是 可选:
componentName
是自解释的<代码>位置将是其中之一
'prop'
'context'
'childContext'
(我们只对
'prop'
),而
propFullName
用于处理嵌套 道具,例如
someObj.someKey

有了这些知识,我们现在可以直接调用类型检查器:

PropTypes.number({myProp:'bad'},'myProp');
//=>[错误:提供的'string'类型的未定义'myProp'无效
//到``,应为`编号`.]
看到了吗?如果没有所有的参数,就没有那么有用了。这样更好:

PropTypes.number({myProp:'bad'},'myProp','MyComponent','prop')
//=>[错误:提供的'string'类型的'myProp'无效
//到“MyComponent”,应为“number”。]
数组类型检查器 文档没有提到的一点是,当您提供自定义类型时 检查到
PropTypes.arrayOf
,将为每个数组调用它 元素,前两个参数将是数组本身和 当前元素的索引。现在我们可以开始画草图了 我们的类型检查器:

函数validArrayItem(arr、idx、组件名称、位置、propFullName){
var obj=arr[idx];
console.log(propFullName,obj);
//1.使用'PropTypes.Object'检查'obj'是否为对象`
//2.检查其所有键是否符合指定的格式
//3.检查其所有值是否都是数字
返回null;
}
到目前为止,它总是返回
null
(表示有效的道具),但我们 加入一个
控制台。log
,查看正在发生的事情。现在我们可以 像这样测试它:

var-typeChecker=PropTypes.arrayOf(validArrayItem);
var myArray=[{foo:1},{bar:'qux'}];
var props={myProp:myArray};
类型检查器(props,'myProp','MyComponent','prop');
//->myProp[0]{foo:1}
//myProp[1]{bar:'qux'}
//=>空
如您所见,
propFullName
对于第一项和第二项是
myProp[0]
myProp[1]
第二个

现在让我们充实一下函数的三个部分

1.使用
PropTypes.Object检查
obj
是否为对象 这是最简单的部分:

函数validArrayItem(arr、idx、组件名称、位置、propFullName){
var obj=arr[idx];
var props={};
props[propFullName]=obj;
//使用'PropTypes.Object'检查'obj'是否为对象`
var isObjectError=PropTypes.object(props、propFullName、componentName、location);
if(isObjectError){返回isObjectError;}
返回null;
}
var typeChecker=PropTypes.arrayOf(validArrayItem);
var props={myProp:[{foo:1},'bar']};
类型检查器(props,'myProp','MyComponent','prop');
//=>[错误:提供给的'string'类型的'myProp[1]`无效
//`MyComponent`,应为`object`.]
太好了!接下来

2.检查其所有键是否符合某些指定格式 在你的问题中,你说“每个键都应该是一个字符串”,但所有的键都是对象 JavaScript中的键是字符串,所以我们可以任意地说,这是我们想要的 测试所有键是否都以大写字母开头。让我们做一个定制 请键入以下内容的检查程序:

var以大写字母开头;
乐趣
...
someArray: React.PropTypes.arrayOf(
  React.PropTypes.objectOf(React.PropTypes.number)
)
...
someArray: ImmutablePropTypes.listOf(ImmutablePropTypes.mapOf({
  React.PropTypes.number, // validates values
  React.PropTypes.string, // validates keys
}))
// An object with property values of a certain shape
optionalObject: PropTypes.objectOf(
  PropTypes.shape({
    color: PropTypes.string.isRequired,
    fontSize: PropTypes.number
  })
);