React中如何正确导出可复用的Media Queries媒体查询
问题根源
你写的代码不生效有两个核心原因:
- 你定义的
MediaQueries是React函数组件,内部声明的isLargerThanMobile等变量都是组件内部的局部变量,根本没有对外暴露,直接访问MediaQueries.isLargerThanMobile只能拿到undefined useMediaQuery是React Hook,遵循React Hook的调用规则:只能在React组件、自定义Hook的顶层作用域调用,不能当作普通对象的属性直接访问使用。
正确复用方案
不要把媒体查询逻辑写成普通组件,封装成自定义Hook即可实现跨文件复用,修改后的独立文件代码:
// /media-query/MediaQueries.js import { useMediaQuery } from 'react-responsive' export const useMediaQueries = () => { const isDesktopOrLaptop = useMediaQuery({ query: '(min-width: 810px)' }) const isLargerThanMobile = useMediaQuery({ query: '(min-width: 480px)' }) const isBigScreen = useMediaQuery({ query: '(min-width: 1824px)' }) const isTabletOrMobile = useMediaQuery({ query: '(max-width: 480px)' }) const isPortrait = useMediaQuery({ query: '(orientation: portrait)' }) const isRetina = useMediaQuery({ query: '(min-resolution: 2dppx)' }) return { isDesktopOrLaptop, isLargerThanMobile, isBigScreen, isTabletOrMobile, isPortrait, isRetina } }
在其他业务组件中按如下方式调用即可正常生效:
import { useMediaQueries } from '../media-query/MediaQueries' const BusinessComponent = () => { // 必须在组件顶层调用自定义Hook const { isLargerThanMobile, isDesktopOrLaptop } = useMediaQueries() return ( <div> {isLargerThanMobile ? <span>非小屏移动端</span> : <span>小屏移动端</span>} </div> ) } export default BusinessComponent
注意事项
- 自定义Hook必须以
use开头命名,这是React的约定规则,可自动触发Hook调用规范校验 - 如果需要在非React组件的普通工具函数中获取视口状态,不要用
useMediaQueryHook,直接使用原生window.matchMediaAPI实现即可,Hook无法在组件渲染流程外生效。
内容的提问来源于stack exchange,提问作者eno-sa
相关产品推荐
相关产品推荐

