这是useMediaQuery 挂钩的预期行为。在MUI docs中有解释:
要执行服务器端的 hydration,钩子需要渲染两次。第一次使用 false,服务器的值,第二次使用解析的值。这种双通道渲染周期有一个缺点。它更慢。如果您只进行客户端渲染,则可以将此选项设置为 true。
因此,要在第一页渲染上获得正确的值,useMediaQuery 挂钩中的noSsr 选项需要为true。
有两种选择:
1) 每个组件:
const mobile = useMediaQuery((theme) => theme.breakpoints.only('mobile'), {noSsr: true});
2) 全局在theme 对象中:
const theme = createTheme({
components: {
MuiUseMediaQuery: {
defaultProps: {
noSsr: true,
},
},
}
显然,这只会在没有服务器端渲染的情况下工作。
下面的原始答案适用于 Material-UI v4,但 Hidden 组件一直是 deprecated in v5。
原答案:
我意识到,通过删除媒体查询并将其替换为 Material-UI <Hidden /> 组件,它可以按照我的意愿工作。
export const ResponsiveMenuItem = forwardRef((props, ref) => {
const { children, ...other } = props;
return (
<>
<Hidden smUp>
<option ref={ref} {...other}>
{children}
</option>
</Hidden>
<Hidden only="xs">
<MenuItem ref={ref} {...other}>
{children}
</MenuItem>
</Hidden>
</>
);
});