I originally followed this project to add Firebase to a Gatsby React app. It involves making a Firebase context, wrapping a root layout with a provider, and then using a withFirebase HOC to wrap components with a Firebase consumer as needed. When I originally did it, it worked fine, but I wanted to move the code into a package I could reuse among my apps. Here's the HOC
export const withFirebase = (Component) => (props) => (
<FirebaseContext.Consumer>
{(firebase) => <Component {...props} firebase={firebase} />}
</FirebaseContext.Consumer>
);
And each page starts with a Layout component that renders this:
<FirebaseContext.Provider value={this.state.firebase}>
<AppWithAuthentication>
{this.props.children}
</AppWithAuthentication>
</FirebaseContext.Provider>
AppWithAuthentication
itself uses the withFirebase
HOC as it needs Firebase to get the AuthUser (which is then stored in a context and passed down through a provider), and it's able to do so just fine.
All the above happens in the package code itself, but when I imported my package into my other React project, trying to use withFirebase
stops working as any components wrapped with it never receive the updated context. I confirm this by checking the Component tree in React Dev tools, the Firebase Provider gets the updated not-null value, and the consumer inside AppWithAuthentication
gets it too. But the consumers inside my actual app don't update (and I have this same problem with the AuthUser context I made in the same library).
I even thought that perhaps somehow the parent was rendering with the updated consumer but the children weren't re-rendering, but after counting the renders and logging them it was clear the components from my app were rendering more times than AppWithAuthentication
. To make it a bit clearer, here's my component tree (starting from the Layout component at page root):
Here's Provider showing a value:
Here's AppWithAuthentication
's consumer showing a value:
And here's the consumer from inside my application that doesn't have a value:
I'm completely stuck here and would appreciate any insight.
EDIT:
After more testing I found some more information but I'm still stuck. It would seem that when reloading my page, the Layout
component renders 2 times, the Header
and AppWithAuthentication
components each renders 4 times, and the Login component renders only 1 time. Is this why the consumers aren't updating? (But then why does the Header
component not get any updates when its updating as much as AppWithAuthentication
?)
EDIT 2:
After more research, I think this issue has something to do with webpack? I'm using Neutrino.js to make my component library, and I take the output of its build as the library. I found this question that seemed similar and tried implementing the fix like so in my .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");
}],
};
But it didn't fix the issue. Has anyone encountered issues with webpack breaking React context?