React JS:找出组件是否在上下文提供程序内

KWe*_*iss 5 reactjs

我正在使用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>
  }
}
Run Code Online (Sandbox Code Playgroud)

这个问题不是专门针对测试的。在其他情况下,组件需要在上下文提供者内部和外部工作。

Est*_*ask 6

没有提供官方方法来检查是否有孩子的<Provider>父母<Consumer>

一般情况下,带值<Consumer>是内还是外没有区别,两种情况都会被赋予值。<Provider>undefinedundefined

可以使用内部_currentValue属性检查当前上下文值,但这可能会导致undefined上下文值误报:

const ChildComponent = () => {
  if (NameConsumer._currentValue !== undefined) {
    // 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>
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这在异步渲染中可能无法按预期工作,并且不建议依赖内部结构。更好的方法是检查测试环境。

一种更可测试的方法是NameContext.Consumer一致地使用而不是NameConsumer,因此Consumer可以在测试中模拟属性。否则,这可能需要模拟NameConsumer定义的模块。