如何使用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>
);

该组件接收 urlkey 的 props,它们是要显示的图像的 URL 和每个渲染图像的键。 在组件中,我们使用 <img/> 元素来显示获取的图像。

第 4 步 — 从 Unsplash 获取和渲染随机图像

Unsplash 提供了一个免费的 API 来获取随机图像。 图像将存储在状态容器中并从状态传递到 DOM。 由于我们将使用 React Hooks,我们将分别使用 useStateuseEffect 处理状态和生命周期方法。

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