reactjs - 当在提供上下文的组件中使用子项时,v16.6.0 或更高版本的上下文 API 不起作用

标签 reactjs typescript react-context tsx

我通过声明 public static contextType 使用 React 的新上下文 API(v16.6.0 或更高版本)在使用上下文的组件内部。 只要声明 Provider 的组件工作正常不直接使用在其 render() 中使用上下文的组件方法。

示例:

ParentWithContext

这是创建和提供上下文的组件。

export const SomeContext = React.createContext({
  someValue: false
});

export default class ParentWithContext extends Component {
  public render(){
    const contextValue = {someValue: true};
    return (
      <SomeContext.Provider value={contextValue}>
        <ChildOne />
        {this.props.children}
      </SomeContext.Provider>
    );
  }
}

请注意,此组件使用 ChildOne render() 中的组件(右下方)方法。

ChildOneChildTwo

这两个组件简单地使用上面的上下文并显示它。

export default class ChildOne extends Component {
  public static contextType = SomeContext;
  public render(){
    return (
      <div>
        {`Context of ChildOne: ${this.context.someValue}`}
      </div>
    );
  }
}

export default class ChildTwo extends Component {
  public static contextType = SomeContext;
  public render(){
    return (
      <div>
        {`Context of ChildTwo: ${this.context.someValue}`}
      </div>
    );
  }
}

index.tsx

class App extends Component {

  render() {
    return (
      <ParentWithContext>
        <ChildTwo />
        <ChildOne />
      </ParentWithContext>
    );
  }
}

运行此示例将产生以下行:

Context of ChildOne: undefined
Context of ChildTwo: true
Context of ChildOne: undefined

所以 ChildTwo似乎从 this.context 收到了正确的信息, 而 ChildOne什么也没收到。

现在到了奇怪的部分(对我来说):当你删除 <ChildOne/>来自 ParentWithContext它突然对ChildOne都有效和 ChildTwo

新建 ParentWithContext

export default class ParentWithContext extends Component {
  public render(){
    const contextValue = {someValue: true};
    return (
      <SomeContext.Provider value={contextValue}>
        {this.props.children}
      </SomeContext.Provider>
    );
  }
}

新的 HTML 输出

Context of ChildTwo: true
Context of ChildOne: true

Running Code

问题

为什么上下文 API (>=v16.6) 在 static contextType 时不工作(使用 Provider)组件直接使用一个子组件,该子组件在其 render() 中使用上下文功能?这是错误还是已知限制?我错过了什么?

附加信息

使用 <SomeContext.Consumer>将按预期工作。

export default class ChildOne extends Component {
  public render(){
    return (
      <SomeContext.Consumer>
        {context =>
          <div>
          {`Context of ChildOne: ${context.someValue}`}
          </div>
        }
      </SomeContext.Consumer>
    );
  }
}

当然这不是这个问题的解决方案,但可能是一个有用的信息。

最佳答案

我正在创建一个 issue on reacts github发现这不是 React 错误,而是 Javascript/Typescript 问题。

总结

错误的导入顺序导致了“错误”。因为 ChildOne 是在声明上下文之前导入的(在 ParentWithContext 中),所以 SomeContext 实际上是 undefinedChildOne 中导入。

import ChildOne from "./ChildOne";

export const SomeContext = React.createContext({
  someValue: false
});

所以一个解决方案是交换这两个语句

export const SomeContext = React.createContext({
  someValue: false
});

import ChildOne from "./ChildOne";

或者简单地(和 IMHO 清洁器)将上下文提取到它自己的文件中。 这样您以后就可以排除任何类似的问题。

关于reactjs - 当在提供上下文的组件中使用子项时,v16.6.0 或更高版本的上下文 API 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54036474/

相关文章:

javascript - 如何使用具有多个数组的对象的钩子(Hook)设置状态?这里如何设置债务人?

javascript - 将前端库导入wix网站

java - 如何在 Play Framework 中重新创建 nginx 的 try_files 以托管 React 站点

Angular:将数据从 Material 对话框传递到未打开对话框的组件

typescript - 如何从父组件提交表单?

javascript - React UseContext 中的数据在一段时间内未定义

reactjs - 在 React Redux 应用程序中使用 OAuth2 刷新 token

javascript - 节点上的 typescript child

reactjs - 从 redux-saga 函数访问 React 上下文值

javascript - React-Leaflet:将 map 控制组件放置在 map 之外?