在Next.js中使用material-ui的useMediaQuery会导致第一次渲染时出现样式 Flink

jk9hmnmh  于 6个月前  发布在  Flink
关注(0)|答案(1)|浏览(69)

Next.js中使用@mui/material/useMediaQuery会导致第一次渲染时出现样式 Flink 。
我知道这是由于useMediaQuery值在服务器端和客户端之间发生了变化。有什么办法可以解决这个问题吗?

import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
...
const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down('md'));
...
<Typography variant={matches ? 'subtitle1' : 'h5'}>
  {text}
</Typography>

字符串
虽然这可以通过如下所示指定display来切换display来轻松解决,但应尽可能避免这种冗长的写作风格。

<Typography sx={{ display: {xs: 'block', md: 'none'} }} variant={'subtitle1'}>
  {text}
</Typography>

<Typography sx={{ display: {xs: 'none', md: 'block'} }} variant={'h5'}>
  {text}
</Typography>

iyfamqjs

iyfamqjs1#

您试图实现的目标是不可能的,因为useMediaQuery钩子使用JavaScript,而服务器端不知道viewport的大小,因此无法猜测matches的值并正确呈现它。
避免这种 Flink 并使服务器呈现的版本正确显示的唯一方法是只使用CSS,而不是JavaScript。不幸的是,您必须坚持使用第二个代码示例中提供的解决方案。
你能做的最好的就是让这个CSS解决方案更具可读性。例如,我喜欢命名我的媒体查询,并像这样使用它们:

const mobileQuery = theme.breakpoints.down('md');
const desktopQuery = theme.breakpoints.up('md');

return (
  <>
    <Typography
      sx={{ [desktopQuery]: { display: 'none' } }}
      variant={'subtitle1'}
    >
      {text}
    </Typography>
  
    <Typography
      sx={{ [mobileQuery]: { display: 'none' } }}
      variant={'h5'}
    >
      {text}
    </Typography>
  </>
)

字符串

相关问题