You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Layout组件实现、路由隐藏头尾及useMediaQuery响应式适配问题

1、特定页面不渲染公共头尾的实现方案

有两种常用的实现方式,可根据项目规模选择:

方案1:通过Layout组件props控制(适合小型项目)

给Layout组件增加可选的显示控制参数,默认显示头尾,需要隐藏的页面主动传入false即可:

// components/Layout/Layout.tsx
import Header from "./Header/Header"
import Footer from "./Footer/Footer"

interface LayoutProps {
  children: React.ReactNode
  // 新增控制参数,默认值为true
  showHeader?: boolean
  showFooter?: boolean
}

const Layout = ({ children, showHeader = true, showFooter = true }: LayoutProps) => {
  return (
    <div className="layout-container">
      {/* 满足条件才渲染对应组件 */}
      {showHeader && <Header />}
      {/* 页面主体用main标签包裹,符合HTML语义规范 */}
      <main className="page-content">
        {children}
      </main>
      {showFooter && <Footer />}
    </div>
  )
}

export default Layout

不需要显示头尾的页面使用方式:

// 以登录页为例
import Layout from "../components/Layout/Layout"
import LoginContainer from "../containers/Login/LoginContainer"

const LoginPage = () => {
  return (
    <Layout showHeader={false} showFooter={false}>
      <LoginContainer />
    </Layout>
  )
}

export default LoginPage

方案2:通过路由元信息统一控制(适合中大型项目,路由集中管理的场景)

如果项目用了React Router等路由库,可以在路由配置里加meta字段标记页面是否需要显示头尾,Layout中自动读取当前路由配置判断,不需要每个页面单独传参:

// 路由配置文件示例(React Router v6)
const routes = [
  {
    path: '/',
    element: <HomePage />,
    meta: { showHeader: true, showFooter: true }
  },
  {
    path: '/login',
    element: <LoginPage />,
    meta: { showHeader: false, showFooter: false }
  },
  // 其他路由配置
]

// 改造Layout组件自动读取路由配置
import { useLocation } from 'react-router-dom'

const Layout = ({ children }: { children: React.ReactNode }) => {
  const location = useLocation()
  // 匹配当前路由的meta配置
  const currentRouteMeta = routes.find(route => route.path === location.pathname)?.meta || {}
  const { showHeader = true, showFooter = true } = currentRouteMeta

  return (
    <div className="layout-container">
      {showHeader && <Header />}
      <main className="page-content">{children}</main>
      {showFooter && <Footer />}
    </div>
  )
}

2、Layout中使用useMediaQuery实现响应式适配的说明

完全可以在Layout组件中使用useMediaQuery钩子做响应式适配,Layout作为全局布局容器,在这里统一处理不同设备的布局逻辑非常合理。
你可以直接使用第三方UI库提供的useMediaQuery钩子,也可以自定义简单的钩子实现:

// 自定义useMediaQuery钩子
import { useState, useEffect } from 'react'

function useMediaQuery(query: string): boolean {
  const [matches, setMatches] = useState(false)

  useEffect(() => {
    const mediaQuery = window.matchMedia(query)
    // 初始化赋值
    setMatches(mediaQuery.matches)
    // 监听屏幕尺寸变化
    const handleChange = (e: MediaQueryListEvent) => setMatches(e.matches)
    mediaQuery.addEventListener('change', handleChange)
    return () => mediaQuery.removeEventListener('change', handleChange)
  }, [query])

  return matches
}

// Layout中使用示例
const Layout = ({ children, showHeader = true, showFooter = true }: LayoutProps) => {
  // 判断当前设备是否为移动端(宽度小于768px)
  const isMobile = useMediaQuery('(max-width: 767px)')

  return (
    <div className={`layout-container ${isMobile ? 'mobile-layout' : 'pc-layout'}`}>
      {showHeader && <Header isMobile={isMobile} />}
      <main className="page-content">{children}</main>
      {showFooter && <Footer isMobile={isMobile} />}
    </div>
  )
}

你可以根据拿到的isMobile变量,调整全局布局样式、向头尾组件传递响应式参数,比如移动端隐藏Header的导航菜单、改为汉堡按钮,调整内容区的内边距等,都可以在这里统一处理。


内容的提问来源于stack exchange,提问作者sunpl13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:09:05