Quick context, I am making a character-building app (think D&D Beyond). Users can log in, use the builder to generate a character, and then later recall and level-up that character. I'm hosting the data on MongoDB and using Realm Web for CRUD on the database. Based on this guide, I'm using React Context to keep track of the logged-in user as they navigate the site. I'm trying to create a widget in the NavMenu that will allow me to see the logged-in user for dev purposes (later, I can make a "Welcome, [name]!"-type greeting), but I keep getting the error that "mongoContext.user" is null. This makes sense, as the Context is set to null with useState, but as soon as the page renders there is an init() function which anonymously logs in the user if they aren't already. I can't seem to understand why this is happening, even after looking at 4 different articles on how to use React Context. Code Snippets below:
App.js
const [client, setClient] = useState(null);
const [user, setUser] = useState(null);
const [app, setApp] = useState(new Realm.App({id: process.env.REACT_APP_REALM_APP_ID}));
//Anonymously logs in to mongoDB App instance on page render
useEffect(() => {
const init = async () => {
if (!user) {
setUser(app.currentUser ? app.currentUser : await app.logIn(Realm.Credentials.anonymous()));
}
if (!client) {
setClient(app.currentUser.mongoClient('mongodb-atlas'));
}
}
init();
}, [app, client, user]);
//Function to render a given component and pass it the mongoContext prop
const renderComponent = (Component, additionalProps = {}) => {
return (
<MongoContext.Consumer>
{(mongoContext) => <Component mongoContext={mongoContext} {...additionalProps} />}
</MongoContext.Consumer>
);
}
return (
<MongoContext.Provider value={{app, client, user, setClient, setUser, setApp}}>
<Layout>
<Switch>
<Route exact path="/" render={() => renderComponent(Home)} />
... other Routes ...
</Switch>
</Layout>
</MongoContext.Provider>
);
}
As outlined in the guide, each Route receives a render function which wraps it in the Context.Consumer component and sends context. I couldn't figure out if this was possible with the Layout component (since it is itself a component wrapper), so instead I used React.useContext() inside the component I need context for: (the component relationship is Layout -> NavMenu -> UserDetail)
UserDetail.jsx
const UserDetail = (props) => {
const mongoContext = React.useContext(MongoContext);
return (
<div>
<h1>Logged in as: {mongoContext.user.id}</h1>
</div>
);
}
This is the component which gives the "mongoContext.user is null" error. The other components seem to use context just fine, as I have done some Create operations with the anonymous user. I can see that it probably has something to do with how the other components are rendered with the Consumer wrapper, but according to every guide I've read, the React.useContext in the UserDetail component should work as well. Thanks for any help, this has completely stymied the project for now.