如何使用React和CSSGrid构建无限滚动图片库
介绍
在本教程中,我们将使用 React 前端 Javascript 框架和 CSS Grid 构建无限滚动图片库,使用 Unsplash API 嵌入照片图像。 使用来自 Scotch.io 的 codepen 编码挑战作为我们代码的基础,我们将使用 React.js 构建接口,使用 Axios 发出 HTTP 请求,以及 react-infinite-scroll 库实现无限滚动功能。
此外,对于本教程,我们将使用 React Hooks 并在整个项目中使用功能组件。
先决条件
对于本教程,使用此 Image Collage Base 代码 作为构建项目的起点。
第 1 步 — 安装所需的软件包
从 CDN 导入所有必需的依赖项。 Codepen 提供了一个搜索栏,您可以使用该搜索栏输入模块的名称,然后从结果中选择一个并将其添加到您的项目中。
安装的依赖项是:
继续Unsplash创建应用程序并获得访问密钥。
第 2 步 — 构建基础组件
在 React 中,父组件的 HTML 模板是用 JSX 编写的。 我们将继续编写这些在 JSX 中制作模板的 HTML 元素。
创建一个功能组件并在 DOM 上渲染:
let Collage = () => {
// Return JSX
return (
<div className="hero is-fullheight is-bold is-info">
<div className="hero-body">
<div className="container">
<div className="header content">
<h2 className="subtitle is-6">Code Challenge #16</h2>
<h1 className="title is-1">
Infinite Scroll Unsplash Code Challenge
</h1>
</div>
// Images go here
</div>
</div>
</div>
);
};
// Render the component to the DOM element with ID of root
ReactDOM.render(<Collage />, document.getElementById("root"));
在这里,您创建了父组件 Collage ,在 JSX 中返回 HTML 元素,并在 ID 为 root 的 DOM 元素中呈现它。 Bulma 类用于提供页面的基本样式。
第 3 步 — 构建单个图像组件
接下来,让我们继续为单个获取的图像创建单个组件。 这将帮助我们设置每个图像的位置。
使用以下命令创建单个功能组件:
const UnsplashImage = ({ url, key }) => (
<div className="image-item" key={key} >
<img src={url} />
</div>
);
该组件接收 url 和 key 的 props,它们是要显示的图像的 URL 和每个渲染图像的键。 在组件中,我们使用 <img/> 元素来显示获取的图像。
第 4 步 — 从 Unsplash 获取和渲染随机图像
Unsplash 提供了一个免费的 API 来获取随机图像。 图像将存储在状态容器中并从状态传递到 DOM。 由于我们将使用 React Hooks,我们将分别使用 useState 和 useEffect 处理状态和生命周期方法。
在 Collage 组件中,创建两个状态变量,一个用于保存传入的图像,另一个用于存储告诉程序是否加载图像的布尔值。
[...] const [images, setImages] = React.useState([]); const [loaded, setIsLoaded] = React.useState(false); [...]
接下来,我们将创建一个使用 Axios 获取 10 个随机图像的函数。 这是通过向 API 端点发出 GET 请求来完成的,同时传递您获得的访问密钥和您想要返回的图像数量。 这样做:
const fetchImages = (count = 10) => {
const apiRoot = "https://api.unsplash.com";
const accessKey = "{input access key here}";
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then (res => {
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
Axios 是一个基于 Promise 的库,在请求的解析上,我们使用 setImages 方法来填充获取的图像,以及传播之前获取的任何图像。 此外,我们将 loaded 的值设置为 true。
现在我们已经将图像存储在状态中,让我们在安装组件后调用这个 fetchImages 函数。 在早期版本的 React 中,我们将使用 componentDidMount 生命周期方法来执行此操作。 但是,React 现在提供了 useEffect 钩子来处理功能组件中的所有生命周期操作。
在 Collage 组件中,在挂载时调用 fetchImages:
[...]
React.useEffect(() => {
fetchImages();
}, []);
[...]
useEffect 钩子接受第二个参数,它是一个数组。 每次更新或修改数组时,挂钩中提供的函数都会运行。
现在您有一个从 Unsplash 获取十张随机图像的页面。 让我们继续在无限滚动容器中渲染图像。
React-infinite-scroll-component 提供了显示加载微调器或任何元素作为占位符的能力,一旦加载器在视图中或接近视图时调用函数以获取更多数据,并显示任何指定的数据。 在返回的 Collage 的 JSX 和 div 的类 header 之后,在无限滚动组件中渲染图像:
<InfiniteScroll
dataLength={images}
next={() => fetchImages(5)}
hasMore={true}
loader={
<img
src="https://res.cloudinary.com/chuloo/image/upload/v1550093026/scotch-logo-gif_jq4tgr.gif"
alt="loading"
/>}
>
<div className="image-grid" style={{ marginTop: "30px" }}>
{loaded ?
images.map((image, index) => (
<UnsplashImage url={image.urls.regular} key={index} />
)): ""}
</div>
</InfiniteScroll>
在 InfiniteScroll 组件中,我们将一个函数传递给 next 参数。 该函数调用fetchImages函数,并传入一个参数5,即要获取的图像数量。 在 loader 参数中,我们在 JSX 中传递了一个图像作为加载占位符。
.map() 用于遍历状态中的 images 数组,并使用 UnsplashImage 组件渲染每个图像。
第 5 步 — 设计画廊
我们将使用 CSS 网格来设置获取图像的样式。 将 CSS 编辑为:
.title {
font-family: 'Carter One';
}
.container {
margin-top: 50px;
text-align: center;
}
.image-grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: minmax(50px, auto);
.image-item:nth-child(5n){
grid-column-end: span 2;
}
img{
display: flex;
width: 100%;
height: 100%;
object-fit: cover;
}
}
这将创建一个具有 250 像素宽度的列的网格并填充整个图像容器。 此外,将行设置为最小 50 像素和最大 auto 以适合每个图像。 我们在每五个图像上使用 grid-column-end 属性,以使其占用两个图像空间而不是一个。
object-fit 属性确保每个图像适合或包含其容器的完整大小。
你可以在这里找到完整的图库 https://codepen.io/Chuloo/full/BMPXqy。
结论
在本教程中,我们使用 React 钩子以及 CSS 网格构建了一个图片库。 您可以尝试使用网格来创建更好的设置。