首页 > web前端 > js教程 > 在 React 中使用 MiniSearch:高级搜索和过滤变得简单

在 React 中使用 MiniSearch:高级搜索和过滤变得简单

Patricia Arquette
发布: 2024-11-29 04:26:09
原创
248 人浏览过

第一章
什么是 MiniSearch 以及它如何增强 JavaScript 过滤?

MiniSearch 是一个轻量级 JavaScript 库,用于在中小型数据集中进行全文搜索。它对数据进行索引并允许高级搜索功能,例如模糊匹配、前缀搜索、按相关性排名和字段加权。

通过模糊匹配,模糊匹配意味着找到单词或单词的一部分,即使它们输入得不完全正确。例如,如果您输入“wlf”而不是“wolf”,模糊搜索仍会找到包含“wolf”的结果。

通过前缀搜索,前缀搜索会查找某事物开头的单词或部分。因此,如果您搜索“汽车”,前缀搜索也会找到“购物车”或“碳酸饮料”。

miniSearch 为我们提供的这些功能可以帮助我们找到我们正在寻找的内容,即使它的输入不完美。因此,使搜索结果更加准确和有用。

我们为什么需要它?

它给我们带来的第一个优势是高级搜索功能:
传统过滤通常匹配精确值或基本模式。 MiniSearch 提供更复杂的文本匹配。这些高级搜索功能可以猜测您的错误,例如如果您输入“bak”而不是“back”,MiniSearch 就会知道您的意思。

与传统过滤/搜索相比,它的另一个优势是相关性排名:
MiniSearch 根据相关性对结果进行排名,从而改善搜索密集型应用程序中的用户体验。这可确保最相关的结果首先出现。例如,如果您搜索“JavaScript”,系统会优先考虑突出或频繁提及“JavaScript”的文档或项目,从而改善整体搜索体验。

现在我们已经解决了这个问题,让我们创建一个基本的 React.js 应用程序,看看如何在客户端使用 MiniSearch。

第二章
如何使用 MiniSearch 设置 React 应用程序:

好的,让我们来设置我们的项目。为了我们建立这个项目,我将使用永远可靠的 vite。我将使用的文本编辑器或 IDE 是坏家伙,Visual Studio 代码编辑器。

我将在终端中按照这些提示设置 Vite。我必须说,我之前已经创建了这些文件夹:

进入 Visual_testing 文件夹:

PS C:\Users\vawkei\Documents> cd .\visual_testing\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

进入building-in-public-slack文件夹:

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

进入迷你搜索文件夹:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
登录后复制
登录后复制
登录后复制
登录后复制

进入前端文件夹:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
登录后复制
登录后复制
登录后复制
登录后复制

然后在前端文件夹中,我将安装 Vite,因为这就是我们想要的位置,在我们的前端文件夹中。

我将用这行代码安装它:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
登录后复制
登录后复制
登录后复制
登录后复制

然后它给了我选择的选项,我将在这里选择 Javascript 和 React。 React 作为框架,Javascript 作为变体。

完成后。迎接我的将是这些:

PS C:\Users\vawkei\Documents> cd .\visual_testing\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

然后我将安装 minisearch 包和react-router-dom 包。虽然我在本教程中不需要react-router包:

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

还将通过运行以下代码安装 scss:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
登录后复制
登录后复制
登录后复制
登录后复制

现在,这不会有后端。相反,我会将数据放置在外部的某个地方。稍后会详细介绍。

因此,如果我们现在通过在终端中运行 npm run dev 来启动我们的小应用程序,我们将在终端中得到如下响应:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
登录后复制
登录后复制
登录后复制
登录后复制

我们必须点击链接(按住Ctrl键单击):

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
登录后复制
登录后复制
登录后复制
登录后复制

如果我们按住 Ctrl 键单击:

Done. Now run:

 npm install
 npm run dev
登录后复制
登录后复制

我们将在浏览器中看到如下所示的页面:

Using MiniSearch in React: Advanced Search and Filtering Made Easy

第三章
清理 App.jsx":

App.jsx 最初看起来像这样:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install minisearch react-router-dom
登录后复制
登录后复制

这就是我们在上图中看到的 React 徽标和 vite 徽标的原因。但是,我们不想使用 App.jsx 的当前内容,因此我们必须清理它。清理后,内容应如下所示:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install sass
登录后复制
登录后复制

这将使我们的浏览器中出现空白屏幕。

第四章
准备项目:创建模拟数据库:

通常情况下,我应该从数据库、superbase、firebase 等获取数据。或者甚至是某个地方的 API。我将从 json 文件获取数据。我将其命名为 db.json。该文件将位于一个名为 data 的文件夹中,该文件夹应该位于我们应用程序的根目录下。 db 文件的内容如下所示:

 VITE v5.4.11  ready in 332 ms

 ➜  Local:   http://localhost:5173/
 ➜  Network: use --host to expose
 ➜  press h + enter to show help
登录后复制
登录后复制

是的!你家的男朋友是个游戏玩家。???只是想让你知道我非常想玩这些游戏。
现在,让我快速浏览一下该文件。

该文件包含一个带有博客条目数组的 JSON 对象。每个对象代表一个视频游戏并具有以下字段:

标题:视频游戏的名称。

文字:游戏的简要说明。

作者:撰写博客条目的人。

id: 每篇博文的唯一标识符。例如:“1”、“2”、“3”

第五章
使用 JSON 服务器设置模拟后端:

要启动并运行数据库,我们必须进入终端。我们可以在终端中打开另一个端口,并在终端中运行以下命令:

http://localhost:5173/
登录后复制
登录后复制
登录后复制
登录后复制

我们得到的回复是这样的:

http://localhost:5173/
登录后复制
登录后复制
登录后复制
登录后复制

这意味着我们的模拟服务器/数据库已准备好进行操作。

第六章
构建前端:创建 BlogList 组件:

好吧!现在我将进入 src 文件夹并在其中创建一个组件文件夹。在组件文件夹中,我将创建另一个文件夹,将其命名为 blog。在 blog 文件夹中,我将创建另一个名为 blog-list 的文件夹。在这个博客列表文件夹中,我将创建两个文件。 BlogList.jsx 和 BlogList.module.scss。这里不会涉及后者。

然后像这样设置 BlogList 组件:

PS C:\Users\vawkei\Documents> cd .\visual_testing\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

第七章
React 中的路由:在 App.jsx 中渲染 BlogList:

现在我们已经构建了 BlogList 的基本结构,我们必须将其连接到 App.jsx,以便它可以在屏幕/浏览器上呈现。为此,我们深入研究 App.jsx 文件,并编写以下代码:

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

没有涉及布局,因为它在这里没有用。

然后在 main.jsx 中,我们将在那里设置浏览器路由器,如下所示:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
登录后复制
登录后复制
登录后复制
登录后复制

完成所有这些后,App.jsx 中发生的任何事情现在都可以在我们的浏览器/屏幕中看到。

第八章
返回BlogList.jsx:
在 BlogList.jsx 中设置博客和加载状态

在这里,我将创建一些要使用的状态,并且还将从在 localhost:8000 上运行的本地服务器获取博客数据。

我要创建的第一个状态是博客。当应用程序渲染时,它将作为一个空数组开始,稍后当我们从模拟服务器收到博客数据时,它将被更新。

然后我将创建的第二个状态将用于加载。它将跟踪数据是否仍在加载。它以 false 开头,可以在获取数据时设置为 true。

呜呜呜呜呜呜呜:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
登录后复制
登录后复制
登录后复制
登录后复制

第九章
显示我们获取的数据:
构建 Jsx:

首先,我将构建 jsx 组件。为此,我将在返回部分写下以下内容:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
登录后复制
登录后复制
登录后复制
登录后复制

第十章
显示我们获取的数据:
useEffect来了:

这没有多大作用。即使我们在控制台中获取数据,它也不会显示在屏幕上。为了让它显示在屏幕上,我们需要 React 的坏蛋之一 useEffect 的帮助。

什么是useEffect?
根据 NetNin​​ja 的说法,“这个钩子在组件的每次渲染时运行一个函数。请记住,组件在首次加载时最初渲染,并且在状态更改时也会发生。它会重新渲染 DOM,因此可以更新浏览器中的状态(更改后的状态)”。

呜呜呜呜呜呜
我们之前写的 fetchBlogs 函数,我们将它放在 useEffect 中:

PS C:\Users\vawkei\Documents> cd .\visual_testing\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

看起来像电影《盗梦空间》吗?冷静点,我很快就会解释。不是电影《预兆》,而是哦!男人们!这是Mern {M.E.R.N}的克里斯托弗·诺兰就在这里。???

然后在 Jsx 中,我们将在那里进行编码:

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

第十二章
MiniSearch 的效果如何:

好的,现在我们可以在屏幕上渲染博客了。现在让我们使用 MiniSearch。整个代码将如下所示:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\
登录后复制
登录后复制
登录后复制
登录后复制

此代码创建 MiniSearch 的新实例以启用全文搜索。它的作用如下:

fields: 指定数据中的哪些字段(标题、作者、文本)将被索引以供搜索。

storeFields: 定义搜索结果中将包含哪些字段。这些字段与索引数据一起存储,以便于检索。

然后这个:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\
登录后复制
登录后复制
登录后复制
登录后复制

此代码为我们提供了页面呈现后已被 miniSearch 索引的文档总数。

现在,让我们更进一步。页面呈现,并且当它呈现时,博客状态最初为空。我们可以在代码中看到这一点:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .
登录后复制
登录后复制
登录后复制
登录后复制


 

之后,我们使用 fetchBlogs 函数获取数据。那里确实有数据,我们通过查找以下代码就知道有数据:

Done. Now run:

 npm install
 npm run dev
登录后复制
登录后复制

现在这个代码:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install minisearch react-router-dom
登录后复制
登录后复制

这用于删除所有先前索引的项目。如果您需要重新索引新数据或清除当前搜索索引,这非常有用。我们想要重新开始,所以我们使用它。

然后这个:

PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install sass
登录后复制
登录后复制

miniSearch.addAll(data) 方法将 data 数组中的所有项目添加到 MiniSearch 索引中。

获取数据后,我们通过运行以下代码来更新博客:

 VITE v5.4.11  ready in 332 ms

 ➜  Local:   http://localhost:5173/
 ➜  Network: use --host to expose
 ➜  press h + enter to show help
登录后复制
登录后复制

一旦我们更新了博客状态,空的博客数组就会被我们的数据填充。

在此过程中,我们清理了 miniSearch 实例,为使用以下代码建立索引的新数据提供了空间:

http://localhost:5173/
登录后复制
登录后复制
登录后复制
登录后复制

我们通过运行以下代码将接收到的数据添加到其中:

http://localhost:5173/
登录后复制
登录后复制
登录后复制
登录后复制

发生了所有这些,我们的 miniSearch 实例应该加载数据,是的。如果你查看这行代码:

import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  return (
    <>
           {" "}
      <div>
               {" "}
        <a href="https://vite.dev" target="_blank">
                    <img src={viteLogo} className="logo" alt="Vite logo" />     
           {" "}
        </a>
                <a href="https://react.dev" target="_blank">
                   {" "}
          <img src={reactLogo} className="logo react" alt="React logo" />     
           {" "}
        </a>     {" "}
      </div>
            <h1>Vite + React</h1>      <div className="card">
               {" "}
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}       {" "}
        </button>
                <p>
          Edit <code>src/App.jsx</code> and save to test HMR        {" "}
        </p>     {" "}
      </div>      <p className="read-the-docs">Click on the Vite and React logos to learn more       </p>
    </>
  );
}
export default App;
登录后复制

它表明那里有数据索引。但是,重新渲染页面后,我们会丢失数据,因为 miniSearch 会重置。我们通过以下代码知道这一点:

function App() {
  return <>     </>;
}

export default App;
登录后复制

看下面,这是我们的 console.log 在渲染时运行代码时的实际内容。

{
 "blogs": [
 {
 "title": "Wolfenstein",
 "text": "Wolfenstein is a groundbreaking video game series that pioneered the first-person shooter genre. Debuting in 1981, it gained fame with Wolfenstein 3D (1992), placing players in World War II as an Allied spy battling Nazis. Known for its intense gameplay, alternate history, and stealth-action elements, the series continues to evolve with modern reboots and thrilling narratives.",
 "author": "voke",
 "id": "1"
 },
 {
 "title": "Bioshock",
 "text": "BioShock is a critically acclaimed video game series blending first-person shooting with deep storytelling. Set in dystopian worlds like the underwater city of Rapture and floating Columbia, it explores themes of power, morality, and free will. Known for its immersive environments, philosophical depth, and plasmid abilities, BioShock redefined narrative-driven gaming since its debut in 2007.",
 "author": "ese",
 "id": "2"
 },
 {
 "id": "3550",
 "author": "jite",
 "title": "Doom",
 "text": "Doom is a legendary first-person shooter series that revolutionized gaming with its 1993 debut. Players battle demons from Hell across Mars and Earth, armed with iconic weapons like the shotgun and BFG. Known for its fast-paced action, heavy metal soundtrack, and gory visuals, Doom remains a cornerstone of the FPS genre and a cultural phenomenon."
 }
 ]
}
登录后复制

第十四章
解决方案:使用 useRef 持续进行 MiniSearch:

为了防止 miniSearch 在每次渲染时重置,我们将其移动到 useRef ,以便相同的实例在渲染之间保持不变。方法如下:

PS C:\Users\vawkei\Documents> cd .\visual_testing\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

此代码块确保使用 useRef 跨渲染保留 MiniSearch 的单个实例。 miniSearchRef 创建并存储 MiniSearch 实例。

有了这个useRef代码,我们就可以安心了。

解释handleSearch函数:

PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

handleSearch 函数接收用户输入的任何内容,并使用用户的输入更新状态查询。 (事件.目标.值)。如果输入为空,则清除结果状态并停止进一步处理。然后它使用 miniSearch 来搜索模糊匹配的索引数据(允许轻微的不匹配)。然后它会更新结果的状态。

第十五章
最终代码:
所以我们在 BlogList 中的最终代码将如下所示:

从“react”导入 { useEffect, useRef, useState };
从“./BlogList.module.scss”导入类;
从“minisearch”导入 MiniSearch;

const BlogList = () =>; {
  //创建博客和isLoading状态。
  const [博客,setBlogs] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  //创建查询和结果状态。
  const [查询,setQuery] = useState("");
  const [结果,setResults] = useState([]);

  // 检查博客状态是否已满
  console.log(博客);

  const miniSearchRef = useRef(
    新的迷你搜索({
      fields: ["title", "author", "text"], // 要搜索的字段
      storeFields: ["title", "author", "text"], // 要返回的字段
    })
  );
  const miniSearch = miniSearchRef.current;
  console.log("渲染后索引博客:", miniSearch.documentCount);

  //从我们的模拟数据库中获取博客:
  const fetchBlogs = async () =>; {
    setIsLoading(true);

    尝试 {
      const 响应 = 等待 fetch("http://localhost:8000/blogs");

      如果(!response.ok){
        抛出新的错误();
      }

      const data = 等待response.json();
      控制台.log(数据);

      miniSearch.removeAll();

      miniSearch.addAll(数据);
      console.log("索引博客:", miniSearch.documentCount);

      设置博客(数据);
    } 捕获(错误){
      常量消息 =
        错误实例错误? error.message : "出了点问题";
      控制台.log(消息);
    } 最后 {
      setIsLoading(假);
    }
  };

  // 搜索功能:
  const handleSearch = (事件) => {
    setQuery(event.target.value);

    if (event.target.value.trim() === "") {
      返回 setResults([]);
    }

    console.log(event.target.value);

    const searchResults = miniSearch.search(event.target.value, { 模糊: 0.5 });
    console.log("搜索结果:", 搜索结果);
    设置结果(搜索结果);
  };

  // 有条件地显示或搜索结果或博客
  const displayPosts = results.length > > 0 ?结果:博客;

  useEffect(() => {
    获取博客();
  }, []);

  返回 (
    <div>
            <h2>博客列表</h2>
      {正在加载 && <p>正在加载...</p>}     {" "}
      <div className={classes.search}>
               {“”}
        <input placeholder="search" value="{query}" onchange="{handleSearch}">>;     {“”}
      </div>;
            <div className={classes.blogs}>
        {displayPosts.map((博客) => {
          // {blogs.map((blog) => {
          返回 (
            <div>



<p><strong>第十六章</strong><br>
<strong>测试一下:</strong><br>
现在,如果我输入 Wolfenst,将显示以下内容:</p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173282557470183.jpg" alt="Using MiniSearch in React: Advanced Search and Filtering Made Easy"></p>

<p>你可以看到它甚至没有等我完全拼写出来就将其过滤掉。</p>

<p><em>让我们尝试一下批判性地输入:</em></p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173282557528617.jpg" alt="Using MiniSearch in React: Advanced Search and Filtering Made Easy"><br>
Critical 不是标题的名称,但它会搜索我们的文本并找出其中包含 Critical 一词的所有内容。可以肯定地说,《生化奇兵》是唯一具有批判性的内容。</p>

<p><strong>最后的想法</strong><br>
感谢您在 MiniSearch 之旅中陪伴我!我真的很感谢您的时间和耐心,我希望本指南有助于导航和理解如何将 MiniSearch 有效地集成到您的 Reactjs 项目中。</p>

<p><strong>作者简介</strong><br>
Voke Bernard 是一位充满热情、积极进取的 M.E.R.N 开发人员,专门构建动态 React.js 和 Express.js 应用程序。他总是寻求在新项目上进行合作。如果您有兴趣与他合作,请随时联系。</p>


          </div>

            
        
登录后复制

以上是在 React 中使用 MiniSearch:高级搜索和过滤变得简单的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板