ReactiveSearch Quickstart

Step 0: Install ReactiveSearch Native

If you have an existing project, you can install reactivesearch-native module using yarn or npm.

yarn add @appbaseio/reactivesearch-native

or

npm install @appbaseio/reactivesearch-native

If you are starting from scratch, follow the next steps on getting started with reactivesearch-native.

Step 1: Create Boilerplate with CRNA

We will create a search UI based on a books dataset with ReactiveSearch components.

Image

Caption: Final image of how the app will look.

For this quickstart guide, we will use Create React Native App (CRNA) with Expo client.

create-react-native-app my-awesome-mobile-search && cd my-awesome-mobile-search

Install the @appbaseio/reactivesearch-native repo.

yarn add @appbaseio/reactivesearch-native

Step 2: Adding the first component

Lets add our first ReactiveSearch component: ReactiveBase, it is a backend connector where we can configure the Elasticsearch index / authorization setup.

We will demonstrate creating an index using appbase.io service, although you can use any Elasticsearch backend within ReactiveBase.

create an appbase.io app

Caption: For the example that we will build, the app is called good-books-ds and the associated read-only credentials are nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d. You can browse and clone the dataset into your own app from here.

Lets update our src/App.js file to add ReactiveBase component.

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { ReactiveBase } from '@appbaseio/reactivesearch-native';

export default class App extends React.Component {
  render() {
    return (
      <ReactiveBase
        app="good-books-ds"
        credentials="nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d"
      >
        <View style={styles.container}>
            <Text>Hello ReactiveSearch!</Text>
        </View>
      </ReactiveBase>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

This is how the app should look after running the yarn start command.

Screenshot

Step 3: Adding Filter and Result Components

For this app, we will be using DataSearch component for filtering the dataset and ReactiveList component for showing the search results.

Lets add them within the ReactiveBase component. But before we do that, lets look at the important props for each.

<DataSearch
  componentId="searchbox"
  dataField={[
    'original_title',
    'original_title.search',
    'authors',
    'authors.search',
  ]}
  placeholder="Search for books"
/>

The DataSearch component we describe above creates a searchbox UI component that queries on the specifield dataField(s) in the dataset.

Next, we need a component to show the matching results. ReactiveList does exactly this.

<ReactiveList
  componentId="results"
  dataField="original_title"
  size={7}
  showResultStats={false}
  pagination={true}
  react={{
    and: "searchbox"
  }}
  onData={(res) => (
    <View style={styles.result}>
      <Image source={{ uri: res.image }} style={styles.image} />
      <View style={styles.item}>
        <Text style={styles.title}>{res.original_title}</Text>
        <Text>{res.authors}</Text>
      </View>
    </View>
  )}
/>

The react prop here specifies that it should construct a query based on the current selected values of searchbox and ratingsfilter components. Every time the user changes the input value, a new query is fired — you don’t need to write a manual query for any of the UI components here, although you can override it via customQuery prop.

ReactiveSearch uses native-base which uses some fonts which can be included by adding:

async componentWillMount() {
	await Expo.Font.loadAsync({
		Roboto: require('native-base/Fonts/Roboto.ttf'),
		Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
		Ionicons: require('native-base/Fonts/Ionicons.ttf'),
	});
}

Now, we will put all the things together to create the final view.

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
  ScrollView,
  Image
} from 'react-native';
import {
  ReactiveBase,
  DataSearch,
  ReactiveList
} from '@appbaseio/reactivesearch-native';

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      isReady: false
    }
  }

  async componentWillMount() {
		await Expo.Font.loadAsync({
			Roboto: require('native-base/Fonts/Roboto.ttf'),
			Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
			Ionicons: require('native-base/Fonts/Ionicons.ttf'),
		});

		this.setState({ isReady: true });
  }

  render() {
    if (!this.state.isReady) {
      return (
        <View style={styles.container}>
          <Text>Loading...</Text>
        </View>
      )
    }

    return (
      <ReactiveBase
        app="good-books-ds"
        credentials="nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d"
      >
        <ScrollView>
          <View style={styles.container}>
            <DataSearch
              componentId="searchbox"
              dataField={[
                'original_title',
                'original_title.search',
                'authors',
                'authors.search',
              ]}
              placeholder="Search for books"
            />
            <ReactiveList
              componentId="results"
              dataField="original_title"
              size={7}
              showResultStats={false}
              pagination={true}
              react={{
                and: "searchbox"
              }}
              onData={(res) => (
                <View style={styles.result}>
                  <Image source={{ uri: res.image }} style={styles.image} />
                  <View style={styles.item}>
                    <Text style={styles.title}>{res.original_title}</Text>
                    <Text>{res.authors}</Text>
                  </View>
                </View>
              )}
            />
          </View>
        </ScrollView>
      </ReactiveBase>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    padding: 10,
    marginTop: 25
  },
  image: {
    width: 100,
    height: 100
  },
  result: {
    flexDirection: 'row',
    width: '100%',
    margin: 5,
    alignItems: 'center',
  },
  item: {
    flexDirection: 'column',
    paddingLeft: 10
  },
  title: {
    fontWeight: 'bold'
  }
});

If you have followed along so far, you should be able to see the final app:

Image

In the next section we explain about creating the same app outside expo environment.