来自库的反应上下文未在消费者中更新
Posted
技术标签:
【中文标题】来自库的反应上下文未在消费者中更新【英文标题】:React context from library not updating in consumer 【发布时间】:2020-11-25 19:01:11 【问题描述】:我最初关注 this project 将 Firebase 添加到 Gatsby React 应用程序。它包括创建一个 Firebase 上下文,用提供者包装根布局,然后根据需要使用 withFirebase HOC 用 Firebase 消费者包装组件。当我最初这样做时,它运行良好,但我想将代码移动到一个可以在我的应用程序中重用的包中。这是 HOC
export const withFirebase = (Component) => (props) => (
<FirebaseContext.Consumer>
(firebase) => <Component ...props firebase=firebase />
</FirebaseContext.Consumer>
);
每个页面都以一个 Layout 组件开始,该组件呈现:
<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 上下文也有同样的问题)。
我什至认为父级可能以某种方式使用更新的消费者进行渲染,但子级没有重新渲染,但是在计算渲染并记录它们之后,很明显我的应用程序中的组件渲染的次数比 @987654337 多@。为了更清楚一点,这是我的组件树(从页面根目录的 Layout 组件开始):
这里的 Provider 显示一个值:
这里是 AppWithAuthentication
的消费者显示值:
这是我的应用程序内部没有值的消费者:
我完全被困在这里,如果有任何见解,我将不胜感激。
编辑:
经过更多测试后,我发现了更多信息,但我仍然卡住了。似乎在重新加载我的页面时,Layout
组件渲染了 2 次,Header
和 AppWithAuthentication
组件各渲染了 4 次,而 Login 组件仅渲染了 1 次。这就是消费者不更新的原因吗? (但是为什么Header
组件在更新与AppWithAuthentication
一样多时没有得到任何更新?)
编辑 2:
经过更多研究,我认为这个问题与webpack有关?我正在使用 Neutrino.js 来制作我的组件库,并将其构建的输出作为库。我发现this question 看起来很相似,并尝试在我的.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 上下文的问题?
【问题讨论】:
【参考方案1】:我从一个聪明的朋友那里听说问题是因为 React 上下文是在模块级别定义的,因此由于您尝试将上下文放在单独的入口点中,所以事情不会那么顺利。
我认为您可以尝试制作一个 index.js 文件来重新导入和导出所有内容,然后一切都应该正常工作,因为它们都合并到一个模块中。
【讨论】:
是的,最终暂时修复了它。我发现有一篇文章进一步描述了它:***.com/a/60655639/3325942我现在会接受这个答案,但我希望我能找到不同的解决方法,因为只有一个入口点会使导入变得更加混乱。以上是关于来自库的反应上下文未在消费者中更新的主要内容,如果未能解决你的问题,请参考以下文章
从消费者 componentDidMount 更新反应上下文会导致无限重新渲染