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

ROO*_*DAY 5 reactjs webpack react-context

我最初关注这个项目是为了将 Firebase 添加到 Gatsby React 应用程序中。它涉及创建 Firebase 上下文,使用提供者包装根布局,然后使用 withFirebase HOC 根据需要使用 Firebase 使用者包装组件。当我最初这样做时,它工作得很好,但我想将代码移动到一个可以在我的应用程序中重用的包中。这是 HOC

export const withFirebase = (Component) => (props) => (
  <FirebaseContext.Consumer>
    {(firebase) => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);
Run Code Online (Sandbox Code Playgroud)

每个页面都以一个呈现以下内容的布局组件开始:

<FirebaseContext.Provider value={this.state.firebase}>
  <AppWithAuthentication>
    {this.props.children}
  </AppWithAuthentication>
</FirebaseContext.Provider>
Run Code Online (Sandbox Code Playgroud)

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

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

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

这是 Provider 显示的值:
有价值的提供者

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

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

我完全被困在这里,希望得到任何见解。

编辑:经过更多测试后,我发现了更多信息,但我仍然陷入困境。看起来,当重新加载我的页面时,该Layout组件呈现 2 次,HeaderAppWithAuthentication组件各呈现 4 次,而 Login 组件仅呈现 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");
    }],
};
Run Code Online (Sandbox Code Playgroud)

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

小智 6

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

我认为您可以尝试制作一个 index.js 文件来重新导入和导出所有内容,然后一切都应该可以正常工作,因为它全部合并在一个模块中。