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};
You’re good to go with react native real time search!
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.