How to Add Search to a React App with Fuse.js
https://www.freecodecamp.org/news/how-to-add-search-to-a-react-app-with-fuse-js/
Last updated
Was this helpful?
https://www.freecodecamp.org/news/how-to-add-search-to-a-react-app-with-fuse-js/
Last updated
Was this helpful?
Colby Fayock
Search is a powerful way help people visiting your site find the content that's most important to them. But often it's really challenging to figure out the rules and logic to make that happen. In this article, we'll see how can we can use fuse.js to add search to our apps.
Fuse.js is a JavaScript library that provides fuzzy search capabilities for applications and websites. It's nice and easy to use out of the box, but also includes configuration options that allow you to tweak and create powerful solutions.
Whether you're a content creator or are trying to sell a product with your website, it's important to help your visitors actually find what they're looking for.
If you're building an ecommerce website, you want someone to be able to easily find your Bender vinyl figures rather than having to dig through the entire catalog first.
We're going to start off with a basic Create React App example. It's going to include some character info as structured data for one of my favorite shows Futurama that's simply dumped out into an HTML list.
With that list, we're going to use fuse.js to provide client-side search capabilities, allowing us to demonstrate searching for the character we're looking for by their name and other details.
To get started, we're going to need content to work with. I got started by building a list of characters from Futurama as structured json data that I put in a list with a fresh Create React App.Futurama character search demo
You'll also notice I've already added an input for our search. It's not yet functional but we'll use that to get started.
If you'd like to start off at the same place, I created a branch with my demo repo that you can clone locally to walk through the project with me!
Or follow along with the commit.
First thing we'll want to do is actually add Fuse.js to our app. In your project, run:
This will save the dependency to our project so that we'll be able to use it in our project.
Next we'll want to import the dependency to our app so that we can start building with it. At the top of your file, in our case src/App.js
if you're following along with me in a new Create React App project, add:
And with that, we're ready to get started!
To use Fuse.js, we'll want to first create a new instance of it.
At the top of your component, add:
With this does:
Creates a new instance of Fuse
Passes in our characters
array of objects
Specifies the 3 keys in our data that we want to search on
Next, to perform the search, we can add:
You'll notice that we have more results than our friend Bender though. Fuse.js provides a "fuzzy search" meaning it tries to help you in case you're not sure what you're looking for or if you're misspelling your query.
To get an idea of how this works, let's add the includeScore
option to our search:
You'll notice that our first result has a really low score. With fuse.js, a lower score means it's closer to an exact match.
A score of 0 indicates a perfect match, while a score of 1 indicates a complete mismatch.
It's saying that is incredibly likely that the first result is what we're looking for, but it's not confident in the others.
So with our results, we want to actually connect that to our UI. If you notice our array output is different than what we are mapping through for the HTML list, so let's create a new variable that we can change it to:
What this is doing is creating a new array using the map method that will only include the item
property from each array object.
Then if we replace our characters
map inside of our list with characterResults.map
:
Now that we have a hard-coded search working, we want someone to actually be able to use the search input to search!
To achieve this, we're going to use the useState
hook and listen for changes to the input
field, which will dynamically create a search for our data.
First, import the useState
hook from React:
Next, let's use that hook to create a state instance:
Here, we're creating a new state of query
that we can update with updateQuery
that defaults to an empty string (''
).
With that, let's tell our search input to use that query
value as it's value:
Now let's add an event handler to our input that we can use to update our state:
And we'll want to create that function so we can use it:
This will update our query
with the input's value any time it changes.
Now that our query
will have what we want to search for, we can update our search instance:
If we wanted to fix this though so that all of our results show when there's no query, we can do so with an if
statement or in my example, a ternary, that will show all of the characters if there is no query:
Fuse.js comes with a lot of options that you can use to tune your search to however you'd like. Want to only show confident results? Use the threshold
option! Want case sensitive queries? Use the isCaseSensitive
option!
https://fusejs.io/api/options.html
Sometimes you want someone to be able to link to a particular set of results. To do this, we might want to be able to add a new URL parameter like ?q=bender
.
To make this work, you can grab that URL parameter with javascript and use that value to set our query
state.
If you want to test that it's working, you can console.log(Fuse)
and see our Fuse
class we'll use to create our search capabilities.Imported fuse.js class
And if we console log out the results, we can see:Basic fuse.js search results
Now we can see the score
attribute in our results object.Fuse.js search results with score
We can now see that our page only shows the results for "bender"!Demo with filtered results
At this point, nothing should be different, as we are using a blank query.Demo with filtered results - nothing changed
And now if you reload the page, it's blank! ?Demo with no results
That's because by default, Fuse sees our empty query and doesn't match it to anything. If we now search for something like slurms
, we can see our search dynamically update with results!Demo with results for "slurms"
Demo with all results
And with that, we have our basic search!Demo with filtered results for "zoidberg"