I have a React app set-up according to a Model-View-Presenter architecture, using MobX Lite to handle states, but I am having issues with my components not re-rendering properly on state changes.
My issue is that my Navbar
doesn’t update properly after logging in. Using conditional rendering, the Login
button should change to Logout
, but this doesn’t happen.
See my code below.
const Navbar = observer(({model} : {model: LeaderBoardModel}) => {
const provider = new GoogleAuthProvider();
function handleHomeButtonClick(){
}
function handleCreateMatchButtonClick(){
}
function handleLoginButtonClick(){
signInWithPopup(auth, provider).then((result) => {
model.setUser(result.user);
console.log("Logged in as: ", result.user.displayName);
});
}
function handleLogoutButtonClick(){
signOut(auth);
}
return (
<div>
<NavbarView
model={model}
handleHomeButtonClick={handleHomeButtonClick}
handleCreateMatchButtonClick={handleCreateMatchButtonClick}
handleLoginButtonClick={handleLoginButtonClick}
handleLogoutButtonClick={handleLogoutButtonClick}>
</NavbarView>
</div>
)
})
export function NavbarView({model, handleHomeButtonClick, handleCreateMatchButtonClick, handleLoginButtonClick, handleLogoutButtonClick}) {
function onHomeButtonClickACB(e){
handleHomeButtonClick();
}
function onCreateMatchButtonClick(e){
handleCreateMatchButtonClick();
}
function onLoginButtonClick(e){
handleLoginButtonClick();
}
function onLogoutButtonClick(e){
handleLogoutButtonClick();
}
return (
<div className="navbar">
<AppBar className="MuiAppBar" position="sticky">
<Toolbar className="MuiToolbar">
<div className="home-button">
<IconButton onClick={(e) => onHomeButtonClickACB(e)}>
<Home/>
</IconButton>
</div>
<div className="create-match-button">
<Button variant="contained" disabled={!model.user} onClick={(e) => onCreateMatchButtonClick(e)}>
{model.user && "Create Match" || !model.user && "Sign in to create match"}
</Button>
</div>
{!model.user && <div className="login-button">
<Button variant="contained" onClick={(e) => onLoginButtonClick(e)}>
Login
</Button>
</div>}
{model.user && <div className="logout-button">
<Button variant="contained" onClick={(e) => onLogoutButtonClick(e)}>
Logout
</Button>
</div>}
</Toolbar>
</AppBar>
</div>
);
}
@action setUser(user: User | null) {
this.user = user;
this.matchUnderCreation.userID = user?.uid;
}
I have used the browser debugger to identify the issue. I can see that, after running the setUser
function, the model has a valid user
, yet this does not trigger the Navbar
to re-render.