通过封装自定义 Hook useIsMobile,可避免在每个组件中重复调用 useTheme 和 useMediaQuery,提升代码复用性与可维护性。
通过封装自定义 hook `useismobile`,可避免在每个组件中重复调用 `usetheme` 和 `usemediaquery`,提升代码复用性与可维护性。
在使用 Material UI(MUI)开发响应式应用时,频繁判断设备是否为移动端(如 useMediaQuery(theme.breakpoints.down('sm')))是一种常见需求。但若在多个组件中重复书写 useTheme() + useMediaQuery() 的组合逻辑,不仅冗余,还增加了维护成本和出错风险。
推荐方案是创建一个轻量、专注的自定义 Hook —— useIsMobile:
// hooks/useIsMobile.ts
import { useMediaQuery, useTheme } from '@mui/material';
export const useIsMobile = () => {
const theme = useTheme();
return useMediaQuery(theme.breakpoints.down('sm'));
};
✅ 使用方式简洁直观:
import { useIsMobile } from '@/hooks/useIsMobile';
function Component1() {
const isMobile = useIsMobile();
return (
<div>
{isMobile ? <mobilelayout></mobilelayout> : <desktoplayout></desktoplayout>}
</div>
);
}
function Component2() {
const isMobile = useIsMobile(); // 同样一行调用,逻辑复用无感知
// ...
}
⚠️ 注意事项:
- useIsMobile 内部严格遵循 Hook 规则(仅在函数组件或自定义 Hook 中调用),不可在条件语句或循环中使用;
- 若需支持多断点(如 isTablet、isDesktop),建议扩展为参数化 Hook,例如 useBreakpoint('md');
- 不推荐用 Context 管理此类派生状态:isMobile 是纯衍生值,无跨层级共享必要,且 Context 会增加不必要的重渲染开销;
- 该 Hook 自动订阅媒体查询变化,响应式更新,无需额外处理。
? 进阶提示:
如项目中存在统一的断点策略,还可将 'sm' 抽取为配置常量(如 BREAKPOINTS.MOBILE),便于全局统一调整。
总之,一个 2 行逻辑的自定义 Hook,即可彻底消除重复声明,让组件更专注业务,让逻辑更清晰可测。











