由于PropTypes
是关于 prop 的“类型”,因此null
是一个空对象,但实际上仍然是一种对象。
但它仍然警告:
Warning: Required prop `profile` was not specified in `Element`. Check the render method of `OtherElement`.
我认为这不应该发生。
它不再是null
后停止警告。 我很确定它应该只在undefined
时发出警告?
null
相当于没有值并且不是对象(空或其他)。 如果您不希望它为null
发出警告,则不要让它成为必需,它具有相同的效果。 我不建议测试密钥的存在。
我同意。 我想不出很多用例,您希望强制用户指定一个值,但又愿意接受 null 作为有效值。 出于实际目的,空值的 isRequired 警告是明智的和预期的行为。
相关: https :
(此问题仍然在搜索结果中突出显示)
我看到的一个常见用例是 React 在对数据的 API 调用完成之前渲染组件。 例如,第一个渲染将渲染一个项目列表 ( items: null
)。 然后 API 调用完成,现在items
填充了一个数组。
我正在尝试执行PropTypes.oneOfType([null, PropTypes.object]).isRequired
,所以无论是 null 还是一个对象,这现在不可能吗?
根据CHANGELOG ,因为15.4.0
它被认为是可能的
实际上,在 15.4.0 中正好相反: Required PropTypes now fail with specific messages for null and undefined.
我也面临这个问题。
@Noitidart的解决方法对我不起作用。 它抛出一个错误说:
Failed prop type: The prop
值is marked as required in
选择, but its value is
null .
我发现要求一个属性但也允许空值真的很有用。
+1 以某种方式允许null
。
我们有一个用例,我们的配置通过 JSON 加载,并且有几个标签配置选项指定应该显示的字符串,如下所示:
{
"title": "my title"
}
所以当不应该显示标题时,我们使用null
来表示这种情况:
{
"title": null
}
(添加并行hasTitle: false
会令人望而却步,因为我们有许多这样的设置。)
对于 JSON 内容,使用 null 是区分未定义( undefined
)和故意省略( null
)的非常有用的方法。
您可以允许 null,将 propType 设置为不需要,因为它不是必需的:P
@jquense谢谢,这非常有帮助! 我已经删除了我之前的评论,因为这个 SO答案说了同样的事情。
@jquense您可以允许 null 和 undefined,但不能允许其中之一。
这就是整个问题! Javascript 提供这两种不同的构造是有原因的,因此强制每个人都将null === undefined
视为 PropTypes 是一种人为的限制。
仅仅因为我希望 PropType 明确允许 null 并不意味着我也应该允许 undefined 。 它们是两种不同的情况,语言是故意这样设计的。
我有一个公关来解决这个疏忽: https :
我想禁止undefined
因为这意味着有一个错字并允许null
因为这意味着调用者显式传入null
。 这就是这个问题的重点。 我知道这个问题已经关闭,因为建议只切换到流,我会研究一下。
@binki允许null
而不是undefined
一种方法是使用您自己的 PropType 验证器函数。
在下面的示例中,仅允许null
或string
。 PropTypes 库在内部使用typeof
来检查字符串,所以我也这样做了。 一个好处是您可以将此函数移到组件之外并根据需要调用它。
static propTypes = {
id: PropTypes.number.isRequired,
email: function(props, propName, componentName) {
const propValue = props[propName] // the actual value of `email` prop
if (propValue === null) return
if (typeof propValue === 'string') return
return new Error(`${componentName} only accepts null or string`)
}
}
我猜这个解决方案偏离了 PropTypes 库的意图 - 我说这是由于以下来自https://github.com/facebook/prop-types/blob/master/factoryWithTypeCheckers.js的 PropTypes 库的代码
在实际验证之前,执行快速检查,其中如果属性值为null
则使用 isRequired 设置的属性会自动抛出错误。 换句话说,他们认为必需的属性为 null 是错误的,而我认为它是具有必需的 null 的有效用例。
if (props[propName] == null) {
if (isRequired) {
if (props[propName] === null) {
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
}
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
}
return null;
} else {
return validate(props, propName, componentName, location, propFullName);
}
出于上述原因,我同意@jharris4 。 null
与undefined
。 将其用作占位符是标准做法。
来自 Mozilla 开发者网络:
值 null 表示有意不存在任何对象值。
null 不是全局对象的属性的标识符,就像 undefined 一样。 相反,null 表示缺乏标识,表明变量不指向任何对象。 在 API 中,通常在可以预期对象但没有相关对象的地方检索 null。
应该允许 null ,至少通过PropTypes.oneOfType([null, PropTypes.string]).isRequired
。
@jquense — 删除isRequired
意味着您可能应该设置默认值。 这是否意味着您现在要为 reducer 中的组件 _and_ 中的初始值设置默认值,所有这些都是为了避免允许null
作为 prop 的值?
在等待 API 调用时,我的选择器中有一堆data || ''
( isRequired
接受空字符串''
,空对象{}
等)完成null
是告诉组件数据即将到来的完美方式,请稍等! (但我不能那样做...)
@puiu91现在有一个很好的解决方案......我将制作一个实用函数以在我们的代码库中使用......因为看起来这个问题不会很快重新打开叹息
我也同意应该有一种标准方式来接受null
作为值,原因与@jharris4和@Findiglay所述的相同,但这不再是继续讨论的地方。 此问题不仅已关闭,而且属于facebook/prop-types 。 我正在关注 facebook/prop-types#90 的拉取请求。
撞。 今天仍然遇到这个问题。 拥有对以下内容的内置支持会很棒:
myObj: PropType.object.isRequiredOrNull :)
我认为这方面的优先级非常低。 Flow 是推荐的方法。 http://flow.org/
@Marujah你的片段不正确。
尝试将 null 传递给组件,您会看到会收到警告:
Warning: Failed prop type: The prop 'theProp' is marked as required in 'TheComponent', but its value is null.
问题是 isRequired 首先被评估,它永远不会让 null 或 undefined 值通过。
如果您有兴趣,可以在上面链接用于解决问题的道具类型的 PR。
哦确实! 再次重新测试你是对的
必须通过 PropTypes 绝对允许要求必须明确提供值或空值。
这是我遇到的用例。 我们有一些回调,90% 的选择器都需要这些回调。 少数不需要它们的是非常具体的用例。 我们有一些新开发人员经常忘记提供所有常见的回调。
我想强制所有这些组件的使用做出有意识的决定,不包括特定的回调,而不是某人只是忘记了一些道具。
是的,我们可以通过 flow 进行我们自己更具体的检查,但这将我们的 props 验证分为两个地方,对于浏览 propTypes 定义的人来说是相当不直观的。
只是想在这里添加我的用例。 我有一个包含数据的 redux 存储,以及获取该数据的时间,如果出现错误等。我的组件需要一个“错误”道具(因此如果无法获取数据,它可以向用户显示错误),数据加载成功时为空,出错时填充。
我将加载器组件( PropTypes.node
)作为props
传递,当我不想渲染加载器时,我传递null
。
Afaik, render
函数在不渲染任何内容时应该返回null
而不是undefined
。 因此,将null
作为值传递给我看起来是正确的方法。
我正在实现 InputNumber 组件( <input type="number">
包装器),所以我有propTypes
作为我的道具value
– PropTypes.number.isRequired
,当我使用我的组件时,我总是通过它的财产。 但是今天我需要在默认情况下传递一个指向值的可空链接,并且我的组件添加了一个警告。 我能想象到的唯一决定是改变propTypes
我的道具value
至PropTypes.oneOfType([PropTypes.number, PropTypes.string])
,并设置defaultProps
为空。 但我觉得这不是正确的,因为 input type=number 应该只适用于数字。
我正在尝试执行
PropTypes.oneOfType([null, PropTypes.object]).isRequired
,所以无论是 null 还是一个对象,这现在不可能吗?
它需要一个函数: Warning: Invalid argument supplied to oneOfType. Expected an array of check functions, but received null at index 1.
因此,您应该提供一个函数,例如:
PropTypes.oneOfType([
() => null,
PropTypes.object
]).isRequired
刚刚遇到这个错误,我写了一个方便的函数来解决它:
function nullable(subRequirement) {
const check = (required, props, key, ...rest) => {
if (props[key] === null) {
return null;
}
const sub = required ? subRequirement.isRequired : subRequirement;
return sub(props, key, ...rest);
};
const fn = check.bind(null, false);
fn.isRequired = check.bind(null, true);
return fn;
}
用法:
static propTypes = {
someCallbackFunction: nullable(PropTypes.func).isRequired,
};
在没有isRequired
情况下使用nullable
是可能的(但毫无意义)。 我使它与isRequired
兼容的原因是它可以与react/require-default-props
eslint 规则一起使用。
我的用例是一系列符合通用 API 的组件,由处理回调的单个组件包装。 null
回调意味着“只读”,因此包装器组件有时会故意传递null
s。 同时,重要的是每个属性都传递给子组件,以确保如果添加了一个新属性,它不会被遗漏。 我也不想为符合此 API 的每个组件提供defaultProps
的 null; 据他们所知,调用者必须指定一个值。
我把之前写的 helper 和一堆测试一起放在一个包里,以证明正确性:
npm install --save git+https://github.com/davidje13/prop-types-nullable.git#semver:^1.0.0
用法:
import PropTypes from 'prop-types';
import nullable from 'prop-types-nullable';
[...]
static propTypes = {
thing: nullable(PropTypes.string).isRequired,
};
新解决方案: PropTypes.oneOfType([PropTypes.object]).isRequired
我收到错误。
怎么修。
./~/prop-types/prop-types.js 中的警告关键依赖项:1:482-489 这似乎是一个预先构建的 javascript 文件。 尽管这是可能的,但不建议这样做。 尝试要求原始来源以获得更好的结果。 @ ./~/prop-types/prop-types.js 1:482-489
我正在尝试执行
PropTypes.oneOfType([null, PropTypes.object]).isRequired
,所以无论是 null 还是一个对象,这现在不可能吗?它需要一个函数:
Warning: Invalid argument supplied to oneOfType. Expected an array of check functions, but received null at index 1.
因此,您应该提供一个函数,例如:
PropTypes.oneOfType([ () => null, PropTypes.object ]).isRequired
实际上我有一个错误,因为最后是'isRequired',同时为null和required是不兼容的......
这对我有用:
PropTypes.oneOfType([
PropTypes.string.isRequired,
() => null
])
@gugol2请注意,您编写的内容只会完全禁用类型检查(您现在可以将数字传递给该道具,或undefined
或任何其他内容); 如果验证成功,您提供的函数应该返回null
如果失败则返回非null
。
如果你想走那条路,你需要更多的东西:
PropTypes.oneOfType([
PropTypes.string.isRequired,
(props, key) => props[key] === null ? null : 'Not null'
])
当然,您可以预先定义看起来很糟糕的辅助函数:
const nullable = (props, key) => props[key] === null ? null : 'Not null'
// ...
PropTypes.oneOfType([PropTypes.string.isRequired, nullable])
仅使用PropTypes.oneOfType([PropTypes.string.isRequired])
也是非常可能的(但我真的不推荐它!)。 但这感觉像是一个错误,我不希望这样的代码在以后的版本中幸存下来。 另请注意,它与先前建议的不起作用的
如果你能等一下,有一个公开的 PR ,它的进展非常缓慢,但显然仍在考虑中。
恕我直言,这是正确的行为,但应该记录下来。
我看到的一个常见用例是 React 在对数据的 API 调用完成之前渲染组件。 例如,第一个渲染将渲染一个项目列表 (
items: null
)。 然后 API 调用完成,现在items
填充了一个数组。
有什么最好的方法来处理这个吗? 我希望这个道具是必需的,但在我从 API 取回它之前它是空的。
PropTypes.oneOfType([ PropTypes.string.isRequired, (props, key) => props[key] === null ? null : 'Not null' ])
@davidje13我在使用这种方法时遇到了一个小问题。 覆盖测试有 1/4 的情况从未被覆盖。
假设我有一个组件 Login,它只有一个 prop 'name' 可以为 null 或需要一个字符串:
const Login = ({name}) => {
return <div>{name}</div>
}
所以它的proptypes是:
Login.propTypes = {
name: PropTypes.oneOfType([
PropTypes.string.isRequired,
(props, key) => (props[key] === null ? null : 'Not null'),
]),
};
当我测试这个组件时,我真的只有 2 个场景,空或一个必需的字符串。
render(<Login name={null} />
render(<Login name={'anyName'} />
但是覆盖率告诉我我的测试只有 75% 的覆盖率。
我想知道对此的官方方法是什么。
听起来您缺少的测试用例是它未通过道具检查的测试用例吗? 即,如果您传递一个数字或未定义或其他不应该有的东西。
听起来您缺少的测试用例是它未通过道具检查的测试用例吗? 即,如果您传递一个数字或未定义或其他不应该有的东西。
不,不是那样。
传递 undefined 不会扩大覆盖范围。
而且我无论如何都不能传递数字,这不是允许的值。
我无法涵盖这种情况。
最有用的评论
我看到的一个常见用例是 React 在对数据的 API 调用完成之前渲染组件。 例如,第一个渲染将渲染一个项目列表 (
items: null
)。 然后 API 调用完成,现在items
填充了一个数组。