如何使用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 网格构建了一个图片库。 您可以尝试使用网格来创建更好的设置。