When I use useMediaQuery
from Material UI in my React app in the top level component (App) of my app, the query doesn’t work (value doesn’t update on window resize) and causes rendering issues (when using Chrome’s dev tools mobile screen emulators). But if I move the query in to a child component (AppContainer), it works. Is it because the containing component needs to have some kind of size attributes?
Here is my top level component with the query:
import firebase from './firebase/Firebase';
import {useState} from "react";
import {AuthContext} from "./contexts/AuthContext";
import useMediaQuery from "@mui/material/useMediaQuery";
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(true);
const [user, setUser] = useState(null);
const isWideScreen = useMediaQuery('(min-width: 500px)', {noSsr: true});
firebase.auth().onIdTokenChanged(async (userObject) => {
setIsLoggedIn(!!userObject);
if (userObject){
await localStorage.setItem('accessToken', await userObject.getIdToken());
}
setUser(userObject);
})
return (
<AuthContext.Provider value={{ isLoggedIn , user }}>
<>
<span>{'isWideScreen:'+ isWideScreen.toString()}</span>
</>
</AuthContext.Provider>
);
}
export default App;
Update: I have found that if I COMMENT OUT the firebase auth onIdTokenChanged line of code, the media query works. But if I keep the firebase auth code in this component, the media query fails to update on resize.
2
Answers
As @LindaPaiste suggested, moving the firebase auth handler code into a useEffect fixed the media query issue.
What I’m seeing here is that you have some wonky stuff relating to the Firebase setup. I can’t say for sure that this will fix your MUI problems, but I would give it a try.
You only need to set the
onIdTokenChanged
handler for your Firebase instance one time. The callback function will still run every time that the id token is changed. You should do this inside of auseEffect
hook with an empty dependency array[]
to run this once at mount (you could use dependencies[setIsLoggedIn, setUser]
and it will behave the same, as these functions never change).The
await
inside oflocalStorage.setItem
is confusing. I would move this to a separate line. You do not need toawait
localStorage.setItem
because that is a synchronous operation.Try this: