react瀑布流实现
实现 React 瀑布流的方法
使用 CSS Grid 实现
CSS Grid 提供了一种简单的方式来实现瀑布流布局。通过设置 grid-auto-flow: dense 和 grid-template-columns,可以自动填充空白区域。
import React from "react";
import "./WaterfallGrid.css";
const WaterfallGrid = ({ items }) => {
return (
<div className="waterfall-grid">
{items.map((item, index) => (
<div key={index} className="grid-item">
<img src={item.image} alt={item.title} />
<h3>{item.title}</h3>
</div>
))}
</div>
);
};
export default WaterfallGrid;
.waterfall-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-flow: dense;
gap: 16px;
}
.grid-item {
break-inside: avoid;
}
使用 CSS Columns 实现
CSS 的多列布局是另一种实现瀑布流的方式,特别适合内容高度不一的场景。
import React from "react";
import "./WaterfallColumns.css";
const WaterfallColumns = ({ items }) => {
return (
<div className="waterfall-columns">
{items.map((item, index) => (
<div key={index} className="column-item">
<img src={item.image} alt={item.title} />
<h3>{item.title}</h3>
</div>
))}
</div>
);
};
export default WaterfallColumns;
.waterfall-columns {
column-count: 3;
column-gap: 16px;
}
.column-item {
break-inside: avoid;
margin-bottom: 16px;
}
使用第三方库 react-masonry-css
对于更复杂的瀑布流需求,可以使用专门为 React 设计的库如 react-masonry-css。
npm install react-masonry-css
import React from "react";
import Masonry from "react-masonry-css";
const breakpointColumnsObj = {
default: 3,
1100: 2,
700: 1
};
const MasonryGrid = ({ items }) => {
return (
<Masonry
breakpointCols={breakpointColumnsObj}
className="masonry-grid"
columnClassName="masonry-grid_column"
>
{items.map((item, index) => (
<div key={index} className="masonry-item">
<img src={item.image} alt={item.title} />
<h3>{item.title}</h3>
</div>
))}
</Masonry>
);
};
export default MasonryGrid;
.masonry-grid {
display: flex;
margin-left: -16px;
width: auto;
}
.masonry-grid_column {
padding-left: 16px;
background-clip: padding-box;
}
.masonry-item {
margin-bottom: 16px;
}
动态加载更多内容
结合 Intersection Observer API 可以实现无限滚动的瀑布流效果。
import React, { useState, useEffect, useRef } from "react";
const InfiniteWaterfall = () => {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
const loaderRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(handleObserver, {
root: null,
rootMargin: "20px",
threshold: 1.0
});
if (loaderRef.current) {
observer.observe(loaderRef.current);
}
return () => observer.disconnect();
}, []);
const handleObserver = (entities) => {
const target = entities[0];
if (target.isIntersecting) {
setPage((prev) => prev + 1);
}
};
useEffect(() => {
// 模拟API调用获取更多数据
fetchMoreItems(page);
}, [page]);
const fetchMoreItems = (pageNum) => {
// 这里替换为实际的API调用
const newItems = Array.from({ length: 10 }, (_, i) => ({
id: i + (pageNum - 1) * 10,
image: `https://picsum.photos/300/400?random=${i + (pageNum - 1) * 10}`,
title: `Item ${i + (pageNum - 1) * 10}`
}));
setItems((prev) => [...prev, ...newItems]);
};
return (
<div className="waterfall-grid">
{items.map((item) => (
<div key={item.id} className="grid-item">
<img src={item.image} alt={item.title} />
<h3>{item.title}</h3>
</div>
))}
<div ref={loaderRef} style={{ height: "20px" }}></div>
</div>
);
};
export default InfiniteWaterfall;
响应式设计考虑
为了确保瀑布流在不同屏幕尺寸下都能良好显示,可以添加媒体查询来调整列数。
@media (max-width: 1024px) {
.waterfall-grid {
grid-template-columns: repeat(2, 1fr);
}
.waterfall-columns {
column-count: 2;
}
}
@media (max-width: 600px) {
.waterfall-grid {
grid-template-columns: 1fr;
}
.waterfall-columns {
column-count: 1;
}
}
以上方法提供了多种实现React瀑布流的方案,从纯CSS解决方案到使用第三方库,开发者可以根据项目需求选择最适合的方式。CSS Grid方案适合现代浏览器且实现简单,CSS Columns方案兼容性更好,而第三方库则提供了更多高级功能和更好的性能优化。







