在 React 中构建一个无限滚动和 Meilisearch Strapi 插件的图书应用
在本教程中,我们将学习如何在无限滚动的情况下以块的形式获取和呈现数据,以及如何集成和使用 meilisearch 插件来搜索书籍。

作者: ** Taminoturoko Briggs**
一次获取大量数据可能会导致一些负面影响,例如使组件渲染缓慢,从而给网站访问者带来糟糕的用户体验。为了解决这个问题,常用的两种模式是无限滚动,我们将在本教程中介绍。
目标
在本教程中,我们将使用 Strapi 构建一个图书应用程序。该应用程序将专注于如何以无限滚动的方式获取和呈现数据块,以及如何集成和使用 meilisearch 插件来搜索书籍。
先决条件
要学习本教程,您应该熟悉 React,并且应该在系统中安装 Node。
Strapi 简介
Strapi 是一个开源、无头的内容管理系统 (CMS)使用 Nodejs Javascript 框架开发,允许快速设计 API 并且可以从任何客户端(React、Vue 等)访问,让开发人员可以自由使用他们的原生工具。
Strapi 包括一个用户友好的管理页面,该页面提供了易于管理和监控内容的功能。可以根据其插件系统自定义管理页面以及创建的 API,以匹配我们的用例,这是 Strapi 的可爱功能之一。
建立一个Strapi项目
设置 Strapi 项目非常简单。就像create-react-app一样,Strapi 也有zwz100024 create-strapi-app zwz100025 zwz100023。
运行以下命令:
$ mkdir 图书应用程序
$ cd book-app
$ npx create-strapi-app@latest book-app-backend --quickstart
上面的命令为我们的应用程序设置了所有必需的依赖项的 Strapi,并创建了一个新文件夹book-app-backend。
安装完成后,服务器将启动,我们可以通过指定的链接在浏览器中查看。在我们的浏览器中,我们如下页面:

在这里,填写所需的详细信息并创建一个用户帐户以访问仪表板。

创建集合类型
在集合类型中,我们将定义我们希望存储在 Strapi 上的内容。为此,首先,单击 Create your first Collection Type 按钮。

在这个页面上,点击 Create new collection type ,我们会看到一个提示要求输入 Display name 和其他信息:

输入 Books 作为显示名称,然后单击 Continue。 在下一个提示中,我们将看到可以为我们的收藏创建的不同字段类型。

在这里,我们将为书籍创建字段。每本书都有作者、描述、图片、previewLink、publishDate、出版商、副标题和标题。这些是我们的书籍收藏类型将包括的字段。除了 authors 将是 JSON 类型之外,所有字段都将是文本字段。

以上是图书数据的所有字段。创建完成后,点击页面右上角的保存按钮。
构建图书应用
图书应用程序将有一个主页,其中将显示我们的 Strapi 收藏中的所有可用图书,我们将使用无限滚动以块的形式获取这些图书。我们将有一个详细页面来显示有关特定书籍的信息,以及一个显示从 Meilisearch 收到的搜索结果的搜索页面。
我已经为 book 应用程序创建了一个 stater 存储库,其中包含我们将使用的模板和要添加的 Strapi 图书数据,我从Google book API获取。
接下来,我们需要克隆初始 GitHub 存储库。在终端中,cd 进入我们之前创建的 book-app 目录,然后输入以下代码行:
$ git clone -b starter https://github.com/Tammibriggs/strapi-book-app.git
$ cd 带书应用程序
$ npm 安装
现在,当我们使用$ npm start命令启动我们的应用程序时,我们将看到这个页面:

如果我们单击一本书,我们将被带到如下所示的详细信息页面:

现在,我们正在从克隆应用程序的 src 目录中的 data.js 文件中获取图书数据。我们将把图书数据移动到 Strapi 并很快使用 meilisearch 从那里获取它,并使用Intersection Observer API实现无限滚动。
向 Strapi 添加数据
在 src 目录下的 data.js 文件中,我们有超过五十四 (54) 个图书数据;让我们把它们移到 Strapi。为此,我们需要首先允许访问 Strapi 集合。导航到边栏的设置中的仪表板。在用户和权限下选择角色。点击 Public,选择 Book, 并选中所有复选框。

然后,单击右上角的 Save 按钮以保存这些更改。
接下来,在 src/pages/Home.js 添加以下导入:
从'axios'导入axios
我们可以在此处导入 axios,因为它已包含在入门应用程序中。接下来,在Home组件中的books状态后添加如下代码行:
// src/pages/Home.js
常量 URL u003d "http://localhost:1337/api/books"
使用效果(()u003d> {
发送数据()
}, [])
常量 sendData u003d async () u003d> {
让 fetchedData;
const fetchCol u003d 等待 axios.get(URL)
fetchedData u003d fetchCol.data.data
如果(!fetchedData.length){
console.log('完成')
尝试 {
book.forEach((book) u003d> {
axios.post(网址,{
数据: {
作者:book.authors,
描述:book.description,
图片:book.image,
预览链接:book.previewLink,
发布日期:book.publishDate,
出版商:book.publisher,
副标题:book.subtitle,
书名:书名,
}})
})
console.log('完成')
} 捕捉(错误){
控制台日志(错误);
}
} 别的 {
console.log("数据已经上传")
}
}
上面的代码检查我们的 Strapi 集合中是否有任何数据,如果没有,它将使用 data.js 文件中的所有数据填充我们的集合。
现在,当我们前往 Strapi 仪表板并单击边栏中的 Content Manager 时,我们会在 Books 集合中看到五十四 (54) 个条目。

接下来,我们将集成和使用 meilisearch 从我们的 Strapi 收藏中获取我们的书籍数据并显示它,并且还将实现搜索功能。为了搜索数据,meilisearch 使用传递给它的查询。当查询为空时,它将返回我们收藏中的所有书籍,我们将显示在主页上,当查询不为空时,它将返回相应的结果。
集成美利搜索
要在本地使用 Meilisearch,我们将下载并运行它的一个实例。这个可以在这里下载。打开下载的应用程序会显示一个终端,该终端具有托管在本地主机上的 Meilisearch 实例:

如果我们在浏览器中导航到指定的 URL,就会看到 Meilisearch 界面。

接下来,我们用不同的终端cd进入book-app-backend目录并使用以下命令安装Strapi-meilisearch插件:
$ npm 安装strapi-plugin-meilisearch
之后,我们重新运行npm run develop以使用新的meilisearch插件重建我们的 Strapi 应用程序。当我们在浏览器中打开 localhost URL 并登录时,我们将被定向到 Strapi 仪表板:

接下来,让我们点击侧边栏上的meilisearch选项,并在 Settings 选项卡中输入 meilisearch 实例的 URL。

点击保存。现在,通过单击复选框将图书收藏添加到 Collections 部分中的 meilisearch:

这样,当我们刷新 meilisearch 实例时,我们将看到 Strapi 集合中的条目。
从Meilisearch获取图书数据
要在前端获取我们的图书数据,我们可以使用为我们提供的搜索路由(例如,这将获取 30 个图书数据:http://127.0.0.1:7700/indexes/book/search? limitu003d30)) 或者我们可以使用 meilisearch 包。在本教程中,我们将使用该软件包,因此我们需要先安装它。
- 在终端中,cd 进入 strapi-book-app 并输入以下命令:
$ npm 安装 meilisearch
1.接下来,在src/pages中的Home.js文件中添加如下导入:
从“meilisearch”导入MeiliSearch;
- 接下来,通过将 Allbooks 替换为空数组来修改图书状态。它应该如下所示:
const [books, setBooks] u003d useState([])
- 现在,在
books状态后添加以下代码行:
// src/pages/Home.js
const fetchData u003d async () u003d> {
const client u003d new MeiliSearch({
主机:'http://127.0.0.1:7700',
})
const index u003d await client.getIndex('book')
const booksData u003d await index.search('*')
setBooks(booksData.hits)
}
上述函数在调用时会从通过meilisearch实例接收的 Strapi 图书集合中返回我们的数据。请注意,在search方法中,我们将 ***** 作为查询传递。这将获取我们所有的数据,限制为二十 (20),这是默认值。这可以是自定义。
要搜索特定数据,我们只需将其传递给search方法。我们将使用它来实现我们的搜索功能。
我们希望在我们的应用程序渲染时调用上述函数,因此我们将在useEffect挂钩中调用它。在Home组件中,使用sendData()函数修改useEffect挂钩,现在如下所示:
// src/pages/Home.js
使用效果(()u003d> {
拿来()
发送数据()
}, [])
有了这个,我们的 Strapi 图书收藏中的数据现在应该显示在我们的应用程序中。接下来,让我们确保当点击图书卡片时,我们会获取该特定图书的详细信息。
去做这个,
- 前往 src/pages/BookDetail.js 并首先添加以下导入:
从'meilisearch'导入MeiliSearch
1.接下来,修改useEffect钩子,如下所示:
// src/pages/BookDetail.js
使用效果(()u003d> {
const fetchData u003d async () u003d> {
const client u003d new MeiliSearch({
主机:'http://127.0.0.1:7700',
})
const index u003d await client.getIndex('book')
常量 bookData u003d 等待 index.getDocument(params.id)
setBook(bookData)
}
拿来()
}, [])
有了这个,当我们点击一本书时,我们应该看到这本书的详细信息。
实现搜索功能
对于搜索功能,当我们在搜索栏中输入查询时,它会将我们带到将查询附加到 URL 的搜索页面。我们将获取该查询并将其传递给 meilisearch 的 search 方法,然后该方法将返回相应的结果:
去做这个,
- 转到 src/pages/Search.js 并首先添加以下导入:
// src/pages/Search.js
从'meilisearch'导入MeiliSearch
从“反应”导入 {useEffect, useState}
1、接下来,在Search组件中的params变量后面添加如下代码行:
// src/pages/Search.js
const [books, setBooks] u003d useState([])
使用效果(()u003d> {
const fetchData u003d async () u003d> {
const client u003d new MeiliSearch({
主机:'http://127.0.0.1:7700',
})
const index u003d await client.getIndex('book')
const booksData u003d await index.search(params.query)
setBooks(booksData.hits)
}
拿来()
},[参数.查询])
上述代码将根据搜索查询返回所有匹配结果,并将其设置为books状态。现在让我们渲染获取的结果。 3. 将return语句中的div修改成现在这样:
// src/pages/Search.js
<div classNameu003d'searchPage 包装器'>
<div classNameu003d'books'>
{书?地图((书)u003d>(
<书
键u003d{book.id}
标题u003d{书名}
图像u003d{书.图像}
作者u003d{book.authors}
出版商u003d{book.publisher}
发布日期u003d{book.publishedDate}
idu003d{book.id}
/>
))}
</div>
</div>
这样,当我们在搜索栏中搜索书籍时,我们将在搜索页面中看到结果。
使用 Intersection Observer API 实现无限滚动
对于无限滚动功能,我们将从 meilisearch 返回的书限制为 15 个,然后当我们滚动到页面底部时,我们将获取并附加另外 15 个数据。
为此,我们将使用Intersection Observer API来了解我们何时到达页面底部,然后从 meilisearch 以 15 个为单位返回书籍,我们将使用 limit 和 ** offset**参数,可以在作为search方法的第二个参数传递的对象中指定。
使用 Intersection Observer 获取新数据
Intersection ObserverAPI 监控观察到的元素何时可见或何时到达预定义的位置,然后触发提供给它的回调函数。要使用此 API,我们将首先在我们获取的数据的底部创建一个元素,该元素将是观察到的元素。然后,当这个元素可见时,我们将调用回调函数,该函数将负责获取和挂起新书数据。
- 在 Home.js 文件中添加以下导入:
从“反应”导入 {useRef,useCallback}
1、在此之后,在div的结束标记(</div>)之后添加以下代码行,其className为books。
// src/pages/Home.js
<div classNameu003d'loader' refu003d{observerElem}>
{books.length !u003du003d 0 &&
<span>{hasNextPage ? 'Loading...' : '没有书了'}</span>
}
</div>
在上面,我们创建了_div_元素,我们要使用Intersection Observers 观察。我们添加了_ref_属性,所以我们可以直接访问它。以上_div_将显示 Loading... or **n***o** 剩余书籍 ***取决于_hasNextPage_这将是一个布尔状态这将是真或假,具体取决于是否还有要获取的数据。
1.接下来,在URL变量后添加如下代码:
// src/pages/Home.js
constobserverElem u003d useRef(null)
常量 [hasNextPage, setHasNextPage] u003d useState(true)
1、接下来在hasNextPage状态后添加如下代码行:
// src/pages/Home.js
const handleObserver u003d useCallback((entries) u003d> {
常量 [目标] u003d 条目
if(target.isIntersecting && hasNextPage) {
console.log('相交')
}
}, [hasNextPage])
使用效果(()u003d> {
常量元素u003dobserverElem.current
常量选项 u003d { 阈值:0 }
const观察者u003d新的IntersectionObserver(handleObserver,选项);
观察者。观察(元素)
return () u003d> 观察者.unobserve(元素)
}, [hasNextPage, handleObserver])
上面的代码会检测观察到的元素何时进入视口,然后调用_handleObserver_callback函数。现在,当我们在浏览器中滚动到页面底部并检查控制台时intersected将被记录。
接下来,让我们创建一个函数,该函数将在我们滚动到页面底部时获取和附加书籍数据。为此,我们将修改fetchData函数以在任何时候使用 limit 和 offset 参数调用时获取 15 本书的新数据,然后我们会将新获取的书籍附加到books状态。
去做这个,
1、首先在hasNextPage状态后添加如下代码:
// src/pages/Home.js
const [offset, setOffset] u003d useState(0)
常量 [lastPage, setLastPage] u003d useState({})
- 接下来,将 fetchData 函数修改为如下所示:
// src/pages/Home.js
const fetchData u003d async () u003d> {
const client u003d new MeiliSearch({
主机:'http://127.0.0.1:7700',
})
const index u003d await client.getIndex('book')
const booksData u003d await index.search('*', {
限制:15,
偏移量:偏移量
})
setBooks([...books, ...booksData.hits])
setLastPage(booksData)
}
接下来,我们需要调用handleObserver中的fetchData(),这样当我们滚动到页面底部时,它就会被调用。
- 修改
handleObserver函数现在如下所示:
// src/pages/Home.js
const handleObserver u003d useCallback((entries) u003d> {
常量 [目标] u003d 条目
if(target.isIntersecting && hasNextPage) {
拿来()
}
}, [fetchData, hasNextPage])
1、最后在fetchData函数后添加如下代码:
// src/pages/Home.js
使用效果(()u003d> {
setOffset(books.length)
如果(books.length < lastPage.nbHits){
setHasNextPage(true)
}别的{
setHasNextPage(假)
}
},[书籍])
这样,我们就完成了无限滚动功能的实现。当我们滚动到页面底部时,将显示新书。
结论
在本教程中,我们通过构建图书应用程序学习了如何使用 meilisearch 在 Strapi 中实现无限滚动和搜索功能。
参考文献
1.查看Meilisearch文档。
2.点击这里查看本教程的完整源代码。
更多推荐
所有评论(0)