Building Algolia Powered Search In React Native
Github Instant Search App
Algolia provides in a nutshell, Search As A Service, which if you think is a
pretty cool service. It takes away all the heavy lifting of building &
maintaining a search infrastructure, gives you a nice API to work with and a
robust monitoring to keep everything in check.
The team at Algolia has open sourced API client for most of the programming
languages & also built libraries for a bunch of popular platforms out there.
React-InstantSearch is one of such library which we will be using in this example.
Here is the demo of what we’re going to build in this blog post
Add the library we’re going to use to build this
yarn add react-instantsearch
Let’s open App.js
in our editor and initialise InstantSearch
<InstantSearch
appId="TLCDTR8BIO"
apiKey="686cce2f5dd3c38130b303e1c842c3e3"
indexName="repositories"
>
<View style={styles.searchBoxContainer}>
<SearchBox />
</View>
<Results />
</InstantSearch>
InstantSearch component above will empower our search –– think of it as a
pipeline which takes appId, apiKey & indexName as a prop and connects us to
Algolia service. This component also takes child components which will provide us with a search box & results provided.
Let’s code SearchBox component to be able to perform search against the data
import { connectSearchBox } from "react-instantsearch/connectors";
//...
const SearchBox = connectSearchBox(({ refine, currentRefinement }) => {
return (
<TextInput
style={styles.textBox}
onChangeText={text => refine(text)}
value={currentRefinement}
placeholder="Search Something"
clearButtonMode="always"
spellCheck={false}
autoCorrect={false}
autoCapitalize="none"
/>
);
});
InstantSearch library ships with connectors which provides ready to use
functions which can be hooked to the components to be able to perform defined
actions –– saving us all the effort of writing those logics.
In this case connectSearchBox
enables us to connect our TextInput
and
perform search directly on our dataset (Pretty Cool? Huh).
Let’s now add Results
component to handle result sets provided by Algolia
service.
import { connectInfiniteHits } from "react-instantsearch/connectors";
//...
const Results = connectInfiniteHits(({ hits, hasMore, refine }) => {
const onEndReached = () => {
if (hasMore) {
refine();
}
};
return (
<FlatList
data={hits}
onEndReached={onEndReached}
keyExtractor={repo => repo.objectID}
renderItem={({ item }) => <Repository repo={item} />}
/>
);
});
Similarly connectInfiniteHits
function provides us with the data that can be used to display the result sets.
Let us now write the component which will be responsible to display search item and highlight searched term
const Repository = ({ repo }) => (
<View style={styles.repoContainer}>
<FontAwesome name="github" style={styles.repoIcon} />
<View style={{ flex: 1 }}>
<Text style={styles.repoTitle}>
<Highlight attributeName="name" hit={repo} style={styles.repoTitle} />
</Text>
<Text
ellipsizeMode="tail"
numberOfLines={2}
style={styles.repoDescription}
>
{repo.description}
</Text>
</View>
<View style={styles.metaContainer}>
<FontAwesome name="star" style={styles.starIcon} />
<Text>{repo.stars}</Text>
</View>
</View>
);
If you’re familiar with React Native than you should be fairly comfortable with the above code except Highlight
component (Don’t worry I’ve explain that below).
Everything is now in place except one thing. Now, Let us write the last piece of the puzzle. I’m going to break down the component into small chunks to make it easier for understanding.
As we would expect there’s a connector ships with the library to help us figure out the part as well
import { connectHighlight } from "react-instantsearch/connectors";
//...
const Highlight = connectHighlight(
({ highlight, attributeName, hit }) => {
const parsedHit = highlight({
attributeName,
hit,
});
If you remember the Repository
component code we’ve used Highlight
component and passed some props (go refer that above). We will accept those props with one more extra prop which is provided by connectHighlight
called highlight
.
We will compose parsedHit
function using highlight
& other props. This
function will return us an array of the objects with a property called
isHighlighted
–– which can be used to build highlight functionality in our
app. Let’s complete the above component code
const highlightedHit = parsedHit.map((part, idx) => {
if (part.isHighlighted) {
return (
<Text key={idx} style={{ backgroundColor: "#ffff00" }}>
{part.value}
</Text>
);
}
return part.value;
});
If the part of the content is highlighted then wrap it with Text
component with a background color yellow else do nothing just return the content.
That’s it! You should now have a fully working search with a searched term
highlight functionality. You can be more creative and add animations or any
other fancy functionality as per your design requirements.
I’ve kept the code snippets to minimal for brevity purpose –– whole code of the
example application shown in the video above is hosted on Github
Source Code: https://github.com/BilalBudhani/react-native-github-algolia-search