🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 21 Min Lesezeit
0

Using MiniSearch in React: Advanced Search and Filtering Made Easy

↗ Quelle (dev.to)
🗣️ Stimme:

Chapter One

What Is MiniSearch and How Does It Enhance JavaScript Filtering?



MiniSearch is a lightweight JavaScript library for full-text search within small to medium datasets. It indexes data and allows advanced search capabilities like fuzzy matching, prefix searches, ranking by relevance, and field weighting.



And by fuzzy matching, fuzzy matching means finding words or parts of words even if they are not typed exactly right. For instance, if you type "wlf" instead of "wolf", a fuzzy search will still find results that include "wolf".



And by prefix searches, prefix search looks for words or parts at the start of something. So, if you're searching for "car," a prefix search would also find "cart" or "carbonated."



These features given to us by miniSearch help us find what we are looking for even if it's not typed perfectly. Thus, making search results more accurate and helpful.



And Why do we Need it?



The first advantage it gives us is Advanced Search Features:

Traditional filtering usually matches exact values or basic patterns. MiniSearch provides more sophisticated text matching. These advanced search features can guess your mistakes, like if you type "bak" instead of "back", MiniSearch knows what you mean.



Another advantage it has over traditional filtering/ search is Relevance Ranking:

MiniSearch ranks results based on relevance, improving user experience in search-heavy applications. This ensures the most relevant results appear first. For instance, if you search for "JavaScript", the system prioritizes documents or items that mention "JavaScript" prominently or frequently, improving the overall search experience.



Now that we have that out of the way, let's create a basic React.js application and see how we use MiniSearch on the clientside.



Chapter Two

How to Set Up a React App with MiniSearch:



Ok, let's set up our project. And for us to set up the project, I will be using the ever-dependable vite. The text editor or IDE I will be using is the bad guy, Visual Studio code editor.



I will be setting up Vite with these prompts in the terminal. And I must say, I have already created these folders prior:



To go inside the visual_testing folder:




CODE
PS C:\Users\vawkei\Documents> cd .\visual_testing\






To go inside the building-in-public-slack folder:




CODE
PS C:\Users\vawkei\Documents\visual_testing> cd .\building-in-public-slack\






To go inside the minisearch folder:




CODE
PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack> cd .\minisearch\






To go inside the frontend folder:




CODE
PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch> cd .\frontend\






Then in the frontend folder, I am going to install Vite, because that's where we want it to be, in our frontend folder.



I will install it with this line of code:




CODE
PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm create vite@latest .






Then it gives me options to choose from, I will be going with Javascript and React here. React as a framework and Javascript as a variant.



Once Done. I will be greeted by these:




CODE
Done. Now run:

npm install
npm run dev






Then I will install the minisearch package and the react-router-dom package. Though I won't be needing the react-router package in this tutorial:




CODE
PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install minisearch react-router-dom






Will also install scss by running this code:




CODE
PS C:\Users\vawkei\Documents\visual_testing\building-in-public-slack\minisearch\frontend> npm install sass






Now, this is not going to have a backend. Instead, I will place the data externally, somewhere. More on that later.



So if we now start our little app by running npm run dev in the terminal, we are gonna get a response like this in the terminal:




CODE
 VITE v5.4.11  ready in 332 ms

➜  Local:   http://localhost:5173/
➜  Network: use --host to expose
➜  press h + enter to show help






We will have to Follow the link (ctrl + click) on this:




CODE
http://localhost:5173/






If we ctrl + click on:




CODE
http://localhost:5173/






We gonna be greeted by a page that looks like this in the browser:





Chapter Eleven

Enhancing the BlogList Component with Search Functionality:



Then we are going to put these lines of code above our useEffect:



CODE
const handleSearch = (event) => {
setQuery(event.target.value);

if (event.target.value.trim() === "") {
return setResults([]); // Clear results if query is empty
}

console.log(event.target.value);

const searchResults = miniSearch.search(event.target.value, { fuzzy: 0.2 });
console.log("searchResults:", searchResults);
setResults(searchResults);
};




Looking like the movie Inception? Just calm down, I will explain shortly. Not the movie Omen, But Oh! Men! this is the Christopher Nolan of Mern {M.E.R.N} right here.😁😁😁



Then in the Jsx, we will code this there:



CODE
<div className={classes.search}>
        <input placeholder="search" value={query} onChange={handleSearch} />
</div>




Chapter Twelve

How it all looks like with MiniSearch:



Ok, now we can render the blogs on our screen. Let's now make use of MiniSearch. The whole code will look like this:



CODE
import { useEffect, useState } from "react";
import classes from "./BlogList.module.scss";
import MiniSearch from "minisearch";

const BlogList = () => {
//create the blog and isLoading state.
const [blogs, setBlogs] = useState([]);
const [isLoading, setIsLoading] = useState(false);

//create the query and results state.
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);

// checking if the blog state has been filled
console.log(blogs);

// bringing in miniSearch and createing an instance:
const miniSearch = new MiniSearch({
fields: ["title", "author", "text"],
storeFields: ["title", "author", "text"],
});

console.log("Indexed Blogs after rendering:", miniSearch.documentCount);

//fetching the blogs from our mock database:
const fetchBlogs = async () => {
setIsLoading(true);

try {
const response = await fetch("http://localhost:8000/blogs");

if (!response.ok) {
throw new Error();
}

const data = await response.json();
console.log(data);

miniSearch.removeAll();

miniSearch.addAll(data);
console.log("Indexed Blogs:", miniSearch.documentCount);

setBlogs(data);
} catch (error) {
const message =
error instanceof Error ? error.message : "Something went wrong";
console.log(message);
} finally {
setIsLoading(false);
}
};

// the search functionality:
const handleSearch = (event) => {
setQuery(event.target.value);

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

console.log(event.target.value);

const searchResults = miniSearch.search(event.target.value, { fuzzy: 0.5 });
console.log("searchResults:", searchResults);
setResults(searchResults);
};

// Conditionally displaying or search results or blogs
const displayPosts = results.length > 0 ? results : blogs;

useEffect(() => {
fetchBlogs();
}, []);

return (
<div>
<h2>BlogList</h2>
{isLoading && <p>Loading...</p>}
<div className={classes.search}>
<input placeholder="search" value={query} onChange={handleSearch} />
</div>
<div className={classes.blogs}>
{displayPosts.map((blog) => {
// {blogs.map((blog) => {
return (
<div
key={blog.id}
className={classes.blog}
style={{ padding: "1rem" }}>
<div className={classes.heading}>
<h2>{blog.title}</h2>
<p>
written by: <span>{blog.author}</span>{" "}
</p>
</div>
<div>{blog.text}</div>
</div>
);
})}
</div>
</div>
);
};

export default BlogList;




Now, if we type in a word in the search input, it's meant to filter it out right? But no. It's not working. What could be wrong? hmmmm!!!



Chapter Thirteen

Explaining What is Really Going on:

The Problem: MiniSearch Resets on Re-Rendering



This part really really kicked me hard in the butt like I was a bad guy in a Jet li movie while I was on it.



Let's go:

First off, this code:



CODE
const miniSearch = new MiniSearch({
fields: ["title", "author", "text"],
storeFields: ["title", "author", "text"],
});




This code creates a new instance of MiniSearch to enable full-text search. Here's what it does:



fields: Specifies which fields (title, author, text) in the data will be indexed for searching.



storeFields: Defines which fields will be included in the search results. These fields are stored alongside the indexed data for easy retrieval.



Then this:



CODE
console.log("Indexed Blogs after rendering:", miniSearch.documentCount);




This code gives us the total number of documents that have been indexed by miniSearch after the page renders.



Now, let's go further. The page renders, and when it renders, the blog state is empty initially. We can see that courtesy of this in our code:



CODE
// checking if the blog state has been filled
console.log(blogs);




 



After which, we get our data using the fetchBlogs function.There is data there for real, we know there's data by looking up this code:



CODE
const data = await response.json();
console.log(data);




Now this code:



CODE
miniSearch.removeAll();




This is used to remove all previously indexed items. This is useful if you need to re-index new data or clear the current search index. We want to have a clean slate so we use it.



Then this:



CODE
miniSearch.addAll(data);




The miniSearch.addAll(data) method adds all the items in the data array to the MiniSearch index.



So after getting the data, we update blogs, by running this code:



CODE
setBlogs(data);




Once we update the blogs state, The empty blogs array gets filled with our data.



In the process, we clean up our miniSearch instance to give room for fresh data to be indexed with this code:



CODE
miniSearch.removeAll();




And we add the received data to it by running this code:



CODE
miniSearch.addAll(data);




With all these that took place, our miniSearch instance should be Loaded with data, yes it is. If you check out this line of code:



CODE
console.log("Indexed Blogs:", miniSearch.documentCount);




It shows that there is data indexed there. However, upon re-rendering the page, we lose the data because miniSearch resets. We know this because of this code:



CODE
console.log("Indexed Blogs after rendering:", miniSearch.documentCount);




And look below, this is the actual content from our console.log upon running the code when it renders.



CODE
[]
BlogList.jsx:21 Indexed Blogs after rendering: 0
BlogList.jsx:14 []
BlogList.jsx:21 Indexed Blogs after rendering: 0
BlogList.jsx:35 (3) [{}, {}, {}]
BlogList.jsx:40 Indexed Blogs: 3
BlogList.jsx:35 (3) [{}, {}, {}]
BlogList.jsx:40 Indexed Blogs: 3
BlogList.jsx:14 (3) [{}, {}, {}]
BlogList.jsx:21 Indexed Blogs after rendering: 0
BlogList.jsx:14 (3) [{}, {}, {}]
BlogList.jsx:21 Indexed Blogs after rendering: 0




Chapter Fourteen

The Solution: Persisting MiniSearch Using useRef:



To prevent miniSearch from resetting on each render, we move it to a useRef so that the same instance persists across renders. Here's how:



CODE
const miniSearchRef = useRef(
new MiniSearch({
fields: ["title", "author", "text"], // Fields to search on
storeFields: ["title", "author", "text"], // Fields to return
})
);
const miniSearch = miniSearchRef.current;
console.log("Indexed Blogs after rendering:", miniSearch.documentCount);




This code block ensures that a single instance of MiniSearch persists across renders using useRef. miniSearchRef creates and stores the MiniSearch instance.



With this useRef code, we should be home and dry.



Explaining the handleSearch function:



CODE
const handleSearch = (event) => {
setQuery(event.target.value);

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

console.log(event.target.value);

const searchResults = miniSearch.search(event.target.value, { fuzzy: 0.5 });
console.log("searchResults:", searchResults);
setResults(searchResults);
};




The handleSearch function takes in whatever the user types, it updates the state query with the user's input. (event.target.value). If the input is empty, it clears the results state and stops further processing. Then it uses miniSearch to search indexed data with fuzzy matching (allows slight mismatches). Then it updates the results' state.



Chapter Fifteen

Final Code:

So our final code in BlogList would look like this:



CODE
import { useEffect, useRef, useState } from "react";
import classes from "./BlogList.module.scss";
import MiniSearch from "minisearch";

const BlogList = () => {
//create the blog and isLoading state.
const [blogs, setBlogs] = useState([]);
const [isLoading, setIsLoading] = useState(false);
//create the query and results state.
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);

// checking if the blog state has been filled
console.log(blogs);

const miniSearchRef = useRef(
new MiniSearch({
fields: ["title", "author", "text"], // Fields to search on
storeFields: ["title", "author", "text"], // Fields to return
})
);
const miniSearch = miniSearchRef.current;
console.log("Indexed Blogs after rendering:", miniSearch.documentCount);

//fetching the blogs from our mock database:
const fetchBlogs = async () => {
setIsLoading(true);

try {
const response = await fetch("http://localhost:8000/blogs");

if (!response.ok) {
throw new Error();
}

const data = await response.json();
console.log(data);

miniSearch.removeAll();

miniSearch.addAll(data);
console.log("Indexed Blogs:", miniSearch.documentCount);

setBlogs(data);
} catch (error) {
const message =
error instanceof Error ? error.message : "Something went wrong";
console.log(message);
} finally {
setIsLoading(false);
}
};

// the search functionality:
const handleSearch = (event) => {
setQuery(event.target.value);

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

console.log(event.target.value);

const searchResults = miniSearch.search(event.target.value, { fuzzy: 0.5 });
console.log("searchResults:", searchResults);
setResults(searchResults);
};

// Conditionally displaying or search results or blogs
const displayPosts = results.length > 0 ? results : blogs;

useEffect(() => {
fetchBlogs();
}, []);

return (
<div>
      <h2>BlogList</h2>
{isLoading && <p>Loading...</p>}     {" "}
<div className={classes.search}>
       {" "}
<input placeholder="search" value={query} onChange={handleSearch} />     {" "}
</div>
      <div className={classes.blogs}>
{displayPosts.map((blog) => {
// {blogs.map((blog) => {
return (
<div
key={blog.id}
className={classes.blog}
style={{ padding: "1rem" }}>
             {" "}
<div className={classes.heading}>
                <h2>{blog.title}</h2>                <p>
written by: <span>{blog.author}</span>                {" "}
</p>             {" "}
</div>
              <div>{blog.text}</div>           {" "}
</div>
);
})}
     {" "}
</div>   {" "}
</div>
);
};

export default BlogList;




Chapter Sixteen

Testing it out:

Now if I type wolfenst, this is what shows:





Critically is not a name of a title, but it searches through our text and brings out every content that has the word critically in it. And it's safe to say that Bioshock is the only content that has critically in it.



Final Thoughts

Thank you for sticking with me through this MiniSearch journey! I truly appreciate your time and patience, and I hope this guide has been helpful in navigating and understanding how to integrate MiniSearch effectively in your Reactjs project.



About the Author

Voke Bernard is a passionate and driven M.E.R.N developer, that specializes in building dynamic React.js and Express.js applications. He is always looking to collaborate on new projects. Feel free to reach out if you are interested in working with him.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Using MiniSearch in React: Advanced Search and Filtering Made Easy

Thematisch verwandte Begriffe: Using, MiniSearch, React, Advanced · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...