Categories: softare development

Real-time Data Search From API Using Search Bar Filter and ListView in React Native

Real-time data search functionality can be very crucial for your React Native app, especially as it begins to scale.

Let’s picture this:

You have a product listing application with hundreds of available products. It will be incredibly difficult and discouraging for users of your app to begin to sift through the products one-by-one. What if they just want to buy a particular product on the spot?

Implementing the search functionality will make it easier for users to have a good experience with your app and save them quality time that would otherwise be needlessly spent going through a boring cinema of your products. No offence ):

So, let’s begin.

In this tutorial, I’m going to assume that you already have some working knowledge of React Native, which means I’m not going to go through the fundamentals of creating a new React Native application. We have already covered that here.

We shall also, as a matter of necessity, use components from React Native Elements, a library that makes creating UI components seamless. This library also depends on another package called react-native-vector-icons.

Also, we shall be working with GET Request API (Application Programming Interface) that list out names by nationality

We are going to add both dependencies to our React Native application as follows:

npm install react-native-vector-icons

//or

yarn add react-native-vector-icons


npm install react-native-elements

//or

yarn add react-native-elements

Next, let’s create a new component called Home.js (You can give it any name of your choice)

import React, {Component} from 'react';

class Home extends Component {

}

export default Home;

Next, We’ll add some state variables to our code

class Home extends Component {

constructor(props) {
    super(props);
    this.state = {
      search: '',
      data: [],
      error: null,
      loading: false,
    };
  }

}

export default Home;

Moving on, we are going to write a function that makes the search

search = async () => {
    const url = `https://api.nationalize.io/?name=` + this.state.search;
    this.setState({loading: true});
    fetch(url, {
      method: 'GET',
    })
      .then(res => res.json())
      .then(res => {
        this.setState({
          data: res.country,
          error: res.error || null,
          loading: false,
        });
      })
      .catch(error => {
        this.setState({error, loading: false});
      });
  };

To make it easier for us to display our data retrieved from our GET Request, we shall be making use of Flatlist. Aha!

So, let’s render our data as follows. Also, don’t forget to import Flatlist from react-native

//required imports
import React, {Component} from 'react';
import {
  View,
  FlatList,
  TouchableOpacity,
  ActivityIndicator,
  StatusBar,
} from 'react-native';
import {SearchBar, Button, ListItem} from 'react-native-elements';


renderSearch = () => {
    return this.state.data.map(item => {
      return (
        <View>
          <Text>{item.name}</Text>
        </View>
      );
    });
  };

  renderItem = ({item}) => (
    <TouchableOpacity
      onPress={() =>
        requestAnimationFrame(() =>
          this.props.navigation.navigate('Description', {
            title: item.title,
            imageName: item.image_url,
            synopsis: item.synopsis,
            episodes: item.episodes,
            rated: item.rated,
          }),
        )
      }>
      <ListItem bottomDivider>
        <ListItem.Content>
          <ListItem.Title>{item.title}</ListItem.Title>
          <ListItem.Subtitle
            style={{color: '#000', textTransform: 'uppercase'}}>
            country: {item.country_id}
          </ListItem.Subtitle>
          <ListItem.Subtitle
            style={{color: '#9D7463', textTransform: 'capitalize'}}>
            probability: {item.probability}
          </ListItem.Subtitle>
        </ListItem.Content>
      </ListItem>
    </TouchableOpacity>
  );

Finally, We will render our component as follows:

 render() {
    return (
      <View style={styles.searchContainer}>
        <StatusBar barStyle="light-content" backgroundColor={primaryColor} />
        <View style={styles.search}>
          <SearchBar
            containerStyle={{width: '70%', height: 80, backgroundColor: '#fff'}}
            placeholder="Search name"
            lightTheme
            platform="ios"
            autoFocus={true}
            showLoading={false}
            autoCorrect={false}
            value={this.state.search}
            onChangeText={search => this.setState({search})}
          />
          <Button
            buttonStyle={{backgroundColor: primaryColor, padding: 9}}
            title="search"
            onPress={() => this.search()}
          />
        </View>

        {this.state.loading ? (
          <ActivityIndicator
            style={{
              position: 'absolute',
              flexDirection: 'row',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              marginTop: 0,
            }}
            size="large"
            color="#0275d8"
          />
        ) : (
          <FlatList
            style={{flex: 1}}
            data={this.state.data}
            renderItem={this.renderItem}
            keyExtractor={item => item.country_id.toString()}
            ItemSeparatorComponent={this.renderSeparator}
            ListHeaderComponent={this.renderHeader}
          />
        )}
      </View>
    );
  }

Here is our full working code:

import React, {Component} from 'react';
import {
  View,
  FlatList,
  TouchableOpacity,
  ActivityIndicator,
  StatusBar,
} from 'react-native';
import {SearchBar, Button, ListItem} from 'react-native-elements';
import {styles, primaryColor} from '../assets/styles/Style';

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      search: '',
      data: [],
      error: null,
      loading: false,
    };
  }

  search = async () => {
    const url = `https://api.nationalize.io/?name=` + this.state.search;
    this.setState({loading: true});
    fetch(url, {
      method: 'GET',
    })
      .then(res => res.json())
      .then(res => {
        this.setState({
          data: res.country,
          error: res.error || null,
          loading: false,
        });
      })
      .catch(error => {
        this.setState({error, loading: false});
      });
  };

  renderSearch = () => {
    return this.state.data.map(item => {
      return (
        <View>
          <Text>{item.name}</Text>
        </View>
      );
    });
  };

  renderItem = ({item}) => (
    <TouchableOpacity
      onPress={() =>
        requestAnimationFrame(() =>
          this.props.navigation.navigate('Description', {
            title: item.title,
            imageName: item.image_url,
            synopsis: item.synopsis,
            episodes: item.episodes,
            rated: item.rated,
          }),
        )
      }>
      <ListItem bottomDivider>
        <ListItem.Content>
          <ListItem.Title>{item.title}</ListItem.Title>
          <ListItem.Subtitle
            style={{color: '#000', textTransform: 'uppercase'}}>
            country: {item.country_id}
          </ListItem.Subtitle>
          <ListItem.Subtitle
            style={{color: '#9D7463', textTransform: 'capitalize'}}>
            probability: {item.probability}
          </ListItem.Subtitle>
        </ListItem.Content>
      </ListItem>
    </TouchableOpacity>
  );

  render() {
    return (
      <View style={styles.searchContainer}>
        <StatusBar barStyle="light-content" backgroundColor={primaryColor} />
        <View style={styles.search}>
          <SearchBar
            containerStyle={{width: '70%', height: 80, backgroundColor: '#fff'}}
            placeholder="Search name"
            lightTheme
            platform="ios"
            autoFocus={true}
            showLoading={false}
            autoCorrect={false}
            value={this.state.search}
            onChangeText={search => this.setState({search})}
          />
          <Button
            buttonStyle={{backgroundColor: primaryColor, padding: 9}}
            title="search"
            onPress={() => this.search()}
          />
        </View>

        {this.state.loading ? (
          <ActivityIndicator
            style={{
              position: 'absolute',
              flexDirection: 'row',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              marginTop: 0,
            }}
            size="large"
            color="#0275d8"
          />
        ) : (
          <FlatList
            style={{flex: 1}}
            data={this.state.data}
            renderItem={this.renderItem}
            keyExtractor={item => item.country_id.toString()}
            ItemSeparatorComponent={this.renderSeparator}
            ListHeaderComponent={this.renderHeader}
          />
        )}
      </View>
    );
  }
}

export default Home;

Don’t run the app yet! Let’s add our style sheet, shall we?

Create a folder called assets. Inside the assets folder, create another folder called styles. Now inside the styles folder, create a file called Style.js and add the following code.

Don’t know how to use an external style sheet in React Native? Check it out here

import {StyleSheet} from 'react-native';

const primaryColor = '#6F3A00';
const secondaryColor = '#00689E';
const white = '#FFF';

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  search: {
    flexDirection: 'row',
    justifyContent: 'space-evenly',
    alignItems: 'center',
  },
  searchContainer: {
    flex: 1,
    backgroundColor: '#fff',
  },
});

export {styles, primaryColor, secondaryColor, white};
React Native API Search Functionality

That’s how we implement a react native real time search.

Enjoy this tutorial? Let me know how it’s going in the comments.

Also support us by sharing, liking and following us on our social media platforms.

Recent Posts

Instagram Extends Reels Duration to 3 Minutes

Regardless of whether TikTok faces a U.S. ban, Instagram is wasting no time positioning itself…

1 day ago

AWS Expands Payment Options for Nigerian Customers, Introducing Naira (NGN) for Local Transactions

Amazon Web Services (AWS) continues to enhance its customer experience by offering more flexible payment…

5 days ago

Why JavaScript Remains Dominant in 2025

JavaScript, often hailed as the "language of the web," continues to dominate the programming landscape…

6 days ago

Amazon Moves to Upgrade Alexa with Generative AI Technology

Amazon is accelerating efforts to reinvent Alexa as a generative AI-powered “agent” capable of performing…

7 days ago

Smuggled Starlink Devices Allegedly Used to Bypass India’s Internet Shutdown

SpaceX's satellite-based Starlink, which is currently unlicensed for use in India, is reportedly being utilized…

1 week ago

Why Netflix Dumped React For its Frontend

Netflix, a pioneer in the streaming industry, has always been at the forefront of adopting…

1 week ago