来自库的反应上下文未在消费者中更新

React context from library not updating in consumer

我最初跟随 this project 将 Firebase 添加到 Gatsby React 应用程序。它涉及创建一个 Firebase 上下文,使用提供者包装根布局,然后使用 withFirebase HOC 根据需要使用 Firebase 消费者包装组件。当我最初这样做时,它运行良好,但我想将代码移动到一个包中,我可以在我的应用程序中重复使用。这是 HOC

export const withFirebase = (Component) => (props) => (
  <FirebaseContext.Consumer>
    {(firebase) => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);

并且每个页面都以呈现此内容的布局组件开头:

<FirebaseContext.Provider value={this.state.firebase}>
  <AppWithAuthentication>
    {this.props.children}
  </AppWithAuthentication>
</FirebaseContext.Provider>

AppWithAuthentication 本身使用 withFirebase HOC,因为它需要 Firebase 来获取 AuthUser(然后将其存储在上下文中并通过提供者向下传递),并且它能够这样做很好。

以上所有发生在包代码本身,但是当我将我的包导入我的另一个 React 项目时,尝试使用 withFirebase 停止工作,因为用它包装的任何组件都不会收到更新的上下文。我通过检查 React Dev 工具中的组件树来确认这一点,Firebase 提供程序获取更新的非空值,AppWithAuthentication 中的消费者也获取它。但是我实际应用程序中的消费者不会更新(我在同一个库中创建的 AuthUser 上下文也有同样的问题)。

我什至认为,也许父级正在使用更新后的消费者进行渲染,但子级并没有重新渲染,但是在计算渲染次数并记录它们之后,很明显我的应用程序中的组件渲染次数比AppWithAuthentication。为了更清楚一点,这是我的组件树(从页面根部的 Layout 组件开始):

这是 Provider 显示的值:

这是 AppWithAuthentication 的消费者显示的值:

这是我应用程序内部的消费者, 没有值:

我完全被困在这里,非常感谢任何见解。

编辑: 经过更多测试后,我发现了更多信息,但我仍然卡住了。似乎在重新加载我的页面时,Layout 组件呈现 2 次,HeaderAppWithAuthentication 组件各呈现 4 次,而登录组件仅呈现 1 次。这就是消费者不更新的原因吗? (但是为什么 Header 组件更新到 AppWithAuthentication 就没有更新?)

编辑 2: 经过更多研究,我认为这个问题与webpack有关?我正在使用 Neutrino.js 来制作我的组件库,并将其构建的输出作为库。我发现 看起来很相似,并尝试在我的 .neutrinorc.js:

中像这样实施修复
const reactComponents = require('@neutrinojs/react-components');

module.exports = {
  use: [reactComponents(),
  (neutrino) => {
     neutrino.config.output.library("upe-react-components");
     neutrino.config.output.libraryTarget("umd");
     neutrino.config.mode("development");
    }],
};

但这并没有解决问题。有人遇到过 webpack 破坏 React 上下文的问题吗?

我从我的一个聪明的朋友那里听说问题是因为 React 上下文是在 module-level 定义的,所以既然你试图将你的上下文放在单独的入口点,事情就不会那么顺利。

我认为您可以尝试制作一个 index.js 文件,该文件 re-imports 并导出所有内容,然后事情应该会正常进行,因为它全部合并到一个模块中。