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

时间:2018-09-04 13:36:14

标签: 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>
  }
}

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

1 个答案:

答案 0 :(得分:2)

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

通常,如果<Consumer>位于<Provider>的内部或外部且值为undefined,则在两种情况下都将为其提供undefined值。

可以使用内部_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>
  }
}

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

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