Im using Material UI on my react app and I'm using useMediaQuery and useTheme from mui. This is the code I have right now. Is there a better way to optimize less code? There are only a few style changes between the 2 codes.
const MainPage = () => {
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down('md'))
return (
<div className='mainPage'>
{
isMatch ? (
<>
<Box sx={{ display: "flex", justifyContent: "center", alignContent: "center", flexDirection: "column", padding: "60px 10px 10px 10px" }}>
<Box component="img" src={LandingImage} sx={{ width: "100%" }} />
<Box sx={{ paddingTop: 8 }}>
<Typography sx={{ fontSize: 26, fontWeight: "bold", fontFamily: "sans-serif", textAlign: "center", paddingBottom: 5 }}>About us</Typography>
</Box>
</Box>
</>
) : (
<>
<Box sx={{ display: "flex", justifyContent: "center", alignContent: "center", flexDirection: "row", paddingTop: 20 }}>
<Box component="img" src={LandingImage} />
<Box sx={{ width: 700, paddingTop: 8 }}>
<Typography sx={{ fontSize: 30, fontWeight: "bold", fontFamily: "sans-serif", textAlign: "center", paddingBottom: 5 }}>About us</Typography>
</Box>
</Box>
</>
)}
</div>
)
}
CodePudding user response:
There are several options. The first is to create a style object in javascript, which can be interacted with like normal javascript. You are already doing this in-line, but if we do it in the code above, we can make it dynamic.
const myOuterBoxStyle = {
display: "flex",
justifyContent: "center",
alignContent: "center",
flexDirection: "row",
paddingTop: 20
}
if (isMatch) {
myOuterBoxStyle.flexDirection = "column";
myOuterBoxStyle.paddingTop = undefined;
myOuterBoxStyle.padding = "60px 10px 10px 10px";
}
Once you do all of the dynamic styling you need, you can make a single return for your component and simply put
<Box sx={{myOuterBoxStyle}}>
The other option is to make a seperate CSS sheet and import it, and then use classes. Something like
.outer-box {
display: "flex";
justify-content: "center";
align-content: "center";
}
.is-match {
flex-direction: "column";
padding: "60px 10px 10px 10px"
}
And then you can either add the is-match
class or, perhaps, the is-not-match
class depending.
The final option is to use a third-party package that does most of this for you, like Tailwind
CodePudding user response:
As the structure of JSX for mobile / desktop is the same, you could drop one of those two JSX templates, build a variable to store component configuration based on isMatch
and pass this variable into component template.
const MainPage = () => {
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down('md'))
// Subset of props, to illustrate the idea.
const config = isMatch ? {fontSize: 26} : {fontSize: 30};
// Here only root <Box/> is configured, but you can configure all the nested components the same way.
return (
<div className='mainPage'>
<Box sx={config}>[...]</Box>
</div>
)
}
(Same with components nested inside <Box/>
- the idea is the same - declare some variables with value based on your state and pass them to JSX declaration)
CodePudding user response:
Mui has breakpoints shorthand syntax, as you can check here.
So, for example, your code will also work with:
const MainPage = () => {
return (
<div className="mainPage">
<Box
sx={{
display: "flex",
justifyContent: "center",
alignContent: "center",
flexDirection: ["column", "column", "row"],
paddingTop: ["60px 10px 10px 10px", "60px 10px 10px 10px", 20]
}}
>
<Box component="img" />
<Box sx={{ width: ["unset", "unset", 700], paddingTop: 8 }}>
<Typography
sx={{
fontSize: [26, 26, 30],
fontWeight: "bold",
fontFamily: "sans-serif",
textAlign: "center",
paddingBottom: 5
}}
>
About us
</Typography>
</Box>
</Box>
</div>
);
};
In the example above i use the Breakpoints as an array and mui
docs says:
The second option is to define your breakpoints as an array, from the smallest to the largest breakpoint.
So imagine that array positions would be: [xs, sm, md, lg, xl]
and the breakpoints are equivalent to theme.breakpoints.up
.
Another way to do it is use Breakpoints as an object:
Simple example
<Box
sx={{
width: {
xs: 100, // theme.breakpoints.up('xs')
sm: 200, // theme.breakpoints.up('sm')
md: 300, // theme.breakpoints.up('md')
lg: 400, // theme.breakpoints.up('lg')
xl: 500, // theme.breakpoints.up('xl')
},
}}
>