/ javascript

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