在 React 中实现响应式布局通常有三大类方案:
✅ 一、用 CSS 实现响应式(最常用)
React 本质上只是 UI 渲染库,真正的响应式布局还是依靠 CSS 来完成。
1. 使用媒体查询(Media Query)
最基础也最通用的方法:
.container {
width: 100%;
}
@media (max-width: 768px) {
.container {
padding: 12px;
}
}
@media (min-width: 1024px) {
.container {
padding: 24px;
}
}
React 组件引用即可:
<div className="container">内容</div>
2. 使用 Flex + Grid 自适应布局
例如:
.list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
<div className="list">
<Card />
<Card />
<Card />
</div>
浏览器会自动根据屏幕宽度调整列数。
3. 使用响应式 CSS 框架
如果你不想写媒体查询,可以使用:
🧩 Ant Design
import { Row, Col } from "antd";
<Row gutter={16}>
<Col xs={24} sm={12} md={8} lg={6}>内容</Col>
<Col xs={24} sm={12} md={8} lg={6}>内容</Col>
</Row>
🧩 Bootstrap
🧩 Tailwind CSS(极推荐)
示例:
<div className="p-4 md:p-8 lg:p-16">
<p className="text-base md:text-xl lg:text-2xl">
响应式文字
</p>
</div>
✅ 二、在 React 中用 JS 监听窗口尺寸(更灵活)
当你需要根据屏幕宽度动态调整 组件逻辑 (例如渲染不同组件)时,你可以使用 useEffect + window.resize:
import { useState, useEffect } from "react";
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return width;
}
使用:
const width = useWindowWidth();
return width < 768 ? <MobileMenu /> : <DesktopMenu />;
✅ 三、使用成熟的 Hook 库
1. useMediaQuery(推荐)
例如 @uidotdev/usehooks:
npm install @uidotdev/usehooks
import { useMediaQuery } from "@uidotdev/usehooks";
const isSmall = useMediaQuery("(max-width: 768px)");
return (
<div>{isSmall ? "移动端" : "桌面端"}</div>
);
2. react-responsive
npm i react-responsive
import { useMediaQuery } from "react-responsive";
const isTabletOrMobile = useMediaQuery({ query: "(max-width: 768px)" });
return <div>{isTabletOrMobile ? "手机" : "电脑"}</div>;
📌 总结:最佳实践
| 场景 | 最佳方案 |
|---|---|
| 单纯布局适配 | CSS Media Query / Grid / Flex |
| 快速项目 / UI 库 | AntD + Col/Row 或 Tailwind CSS |
| 根据屏宽渲染不同组件 | useMediaQuery / JS 监听宽度 |
| 有复杂交互、高度自定义 | 自己写 hook(useWindowWidth) |