In React Native applications, the FlatList
is a component that’s used to efficiently display lists of data that are too big to fit on a single screen. It improves the application’s performance since the data is only rendered when it appears on the screen. However, as the list grows, finding specific items can become difficult. That’s where a search bar comes in handy. Adding a search bar to a FlatList
is important for the following reasons:
It makes the application more user-friendly since the users can quickly find what they’re looking for instead of scrolling endlessly.
It saves users’ time and effort. They don’t have to manually search through a long list to locate an item.
It enhances the overall user experience of the application, making it more enjoyable to use.
The following is a step-by-step method of adding a search bar to a FlatList
.
The first step is to import the necessary components within the application. We need to import the FlatList
along with other required components.
import React, { useState } from "react";import { SafeAreaView, View, Text, TextInput, FlatList, StyleSheet } from 'react-native';import {widthPercentageToDP as wp,heightPercentageToDP as hp,} from 'react-native-responsive-screen';
In the code snippet above:
Line 1: We import useState
to manage states within the application.
Line 2: We import FlatList
along with other components to be used within the application.
Lines 3–6: We import the react-native-responsive-screen
library. It enables us to make the application responsive. You can read more about it in the official documentation. However, usage of this library is optional.
Once the required components have been imported, we need to set up the state variables and initial data for the application. The initial data will be rendered by the FlatList
.
const languages = [{id: 1,title: 'Python',},{id: 2,title: 'Java',},{id: 3,title: 'C++',},{id: 4,title: 'JavaScript',},{id: 5,title: 'Ruby',},{id: 6,title: 'Scala',},{id: 7,title: 'Rust',},{id: 8,title: 'Perl',},{id: 9,title: 'Swift',},{id: 10,title: 'TypeScript',},];const [data, setData] = useState(languages);const [searchText, setSearchText] = useState('');
In the code snippet above:
Lines 1–42: We define the languages
array. The languages
array contains a list of programming languages. Each language is represented as an object with an id
and title
property.
Line 44: We define the state variable data
and set it to the languages
array. We will update this state variable according to the search text entered by the users.
Line 45: We define the state variable searchText
and set it to an empty string. We will update this state variable according to the search text entered by the users.
Once the steps above have been completed successfully, we need to render the UI. This includes the search bar and the rendering of the initial data.
const searchFunction = (text) => {setSearchText(text);}const renderItem = ({ item }) => (<View style={styles.box}><Text style={styles.title}> { item.title } </Text></View>);return (<SafeAreaView style={styles.container}><View style={styles.searchBarContainer}><Text style={styles.title}> Programming Languages </Text><TextInputstyle={styles.searchBar}placeholderTextColor="black"placeholder="Search available languages"value={searchText}onChangeText={text => searchFunction(text)}/></View><View style={styles.listDataContainer}><FlatListdata={ data }extraData={ data }showsVerticalScrollIndicator={ false }renderItem={ renderItem }keyExtractor={(item) => item.id}/></View></SafeAreaView>);const styles = StyleSheet.create({container: {flex: 1,},searchBarContainer: {flex: 1.5,backgroundColor: '#ffffff',alignItems: 'center',justifyContent: 'center',},title: {fontSize: wp(5.5),color: 'black',},searchBar: {width: wp(80),height: hp(6),borderWidth: wp(0.2),borderRadius: wp(3),borderColor: '#999999',backgroundColor: '#ffffff',marginTop: wp(7),paddingLeft: wp(4.5),fontSize: wp(4),color: 'black'},listDataContainer: {flex: 5,alignItems: 'center',justifyContent: 'center',backgroundColor: '#ffffff',},box: {width: wp(90),height: hp(20),borderWidth: wp(0.2),borderColor: 'black',alignItems: 'center',justifyContent: 'center',margin: wp(1)},});
The code snippet above shows part of the application’s code. This code is responsible for rendering the search bar and the initial data. Let’s see it in a bit more detail below:
Lines 1–3: We define the function searchFunction
. This function is called whenever the text within the search bar changes (line 20). At this stage, we only update the state variable searchText
within this function. We’ll add the search logic later.
Lines 5–9: We define the function renderItem
. This function is intended to be passed to the FlatList
component for rendering each item in the languages
array defined previously. It returns a View
component containing the title of the programming language displayed as text using the Text
component.
Lines 12–32: We define the UI for the application. This includes the rendering of the title of the application (line 14), the search bar (lines 15–21), and the initial data (lines 24–30).
Lines 35–76: We define the styles of the application.
Now we need to define the search logic. We need to filter the initial data based on the search text entered by the user within the search bar. Finally, this filtered data will be rendered by the FlatList
component. The code snippet below shows how to do this.
const searchFunction = (text) => {setSearchText(text);text = text.toLowerCase();if (text === "") {setData(languages);}else {let filteredLanguages = languages.filter(language => (language.title.toLowerCase().startsWith(text)))setData(filteredLanguages);}}
In the code snippet above:
Lines 3–10: We modify the previously defined function searchFunction
. First, we convert the search text to lowercase. Then, if the search text is empty, we set the state variable data
to the initial data (languages
array). Otherwise, we filter the languages
array based on the search text entered by the user and set the state variable data
to the filtered data, i.e., filteredLanguages
.
The coding playground below shows the complete code we’ve discussed so far.
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * <p>This source code is licensed under the MIT license found in the LICENSE file in the root * directory of this source tree. */ package com.react_native_application; import android.content.Context; import com.facebook.flipper.android.AndroidFlipperClient; import com.facebook.flipper.android.utils.FlipperUtils; import com.facebook.flipper.core.FlipperClient; import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; import com.facebook.flipper.plugins.inspector.DescriptorMapping; import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; import com.facebook.react.ReactInstanceEventListener; import com.facebook.react.ReactInstanceManager; import com.facebook.react.bridge.ReactContext; import com.facebook.react.modules.network.NetworkingModule; import okhttp3.OkHttpClient; /** * Class responsible of loading Flipper inside your React Native application. This is the debug * flavor of it. Here you can add your own plugins and customize the Flipper setup. */ public class ReactNativeFlipper { public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { if (FlipperUtils.shouldEnableFlipper(context)) { final FlipperClient client = AndroidFlipperClient.getInstance(context); client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); client.addPlugin(new DatabasesFlipperPlugin(context)); client.addPlugin(new SharedPreferencesFlipperPlugin(context)); client.addPlugin(CrashReporterPlugin.getInstance()); NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); NetworkingModule.setCustomClientBuilder( new NetworkingModule.CustomClientBuilder() { @Override public void apply(OkHttpClient.Builder builder) { builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); } }); client.addPlugin(networkFlipperPlugin); client.start(); // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized // Hence we run if after all native modules have been initialized ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); if (reactContext == null) { reactInstanceManager.addReactInstanceEventListener( new ReactInstanceEventListener() { @Override public void onReactContextInitialized(ReactContext reactContext) { reactInstanceManager.removeReactInstanceEventListener(this); reactContext.runOnNativeModulesQueueThread( new Runnable() { @Override public void run() { client.addPlugin(new FrescoFlipperPlugin()); } }); } }); } else { client.addPlugin(new FrescoFlipperPlugin()); } } } }
Note: You can download and execute the code example above on your local system or machine. Follow the official React Native documentation to set up the development environment. The code example above is for the Android operating system.
Free Resources