我使用React的Context API来传递一些上下文到较低级别的组件。
我希望能够在没有上下文提供程序的情况下运行组件(用于测试)。为了使其工作,我需要检查我的组件周围是否有上下文提供程序。
示例代码:
const Wrapper = () => {
// in my real app, there are some levels
// between the provider and the child component
return <NameProvider value={name: 'User'}>
<ChildComponent />
</NameProvider>
}
const ChildComponent = () => {
if (/* what can I put here ? */) {
// inside Provider
return <NameConsumer>
{context => <span>{context.name}</span>}
</NameConsumer>
} else {
// no provider available, e.g. in a test file
return <span>Test Text</span>
}
}
这个问题不是专门关于测试的。还可能存在其他情况,其中组件需要在上下文提供程序内部和外部工作。
3条答案
按热度按时间4smxwvx51#
没有提供官方的方法来检查
<Consumer>
子节点是否有<Provider>
父节点。一般情况下,
<Consumer>
在<Provider>
内部或外部的undefined
值没有区别,在两种情况下都将提供undefined
值。可以使用内部
_currentValue
属性检查当前上下文值,但这可能会导致undefined
上下文值的误报:请注意,在异步呈现中,这可能无法按预期工作,因此不建议依赖内部组件。更好的方法是检查测试环境。
一种更可测试的方法是一致地使用
NameContext.Consumer
而不是NameConsumer
,因此可以在测试中模拟Consumer
属性。否则,这可能需要模拟一个定义了NameConsumer
的模块。z9zf31ra2#
看看上下文。如果未定义,则没有Provider。
我通常使用它的组件,我想独立工作,并成为一个更大的小部件的一部分。看到类似谷歌Map的东西,我想提升Map上下文。
mgdq6dx13#
您可以为上下文设置类似对象的默认值(为了安全起见,不是原始值或null):
现在你可以检查context value了:
它将工作,因为我们必须设置值为上下文提供程序(
<someContext.Provider value={currentContextValue}>
),但新对象的值不等于默认值