Search Filter with React Native on FlatList

react native flatlist search bar
react native searchable flatlist
react native search tutorial
react-native-search-box example
react-native-search-filter github
react native filter array
react native search filter install
textinput search react native

I am trying to search through a flatlist based on a search bar text. The problem I am running into is that when the user mistypes...say they wanted to type "burger" but typed "burget" by mistake then it returns nothing as it should. When the user deletes the "t" then it should re-render the flatlist again with the last text matching the "burge" part.

note: using react-native-elements search bar which allows me to call the text with just e or event.

What I have so far in the Main.js file:

searchText = (e) => {
    let text = e.toLowerCase();
    let trucks = this.state.data;

    // search by food truck name
    let filteredName = trucks.filter((truck) => {
      return truck.name.toLowerCase().match(text); 
    });

    // if no match and text is empty
    if(!text || text === '') {
      console.log('change state');
        this.setState({
          data: initial
        });
      }
    // if no name matches to text output
    else if(!Array.isArray(filteredName) && !filteredName.length) {
      console.log("not name");
      this.setState({
        data: [],
      });
    }
    // if name matches then display
    else if(Array.isArray(filteredName)) {
      console.log('Name');
      this.setState({
        data: filteredName,
      });
    }
   };

<View style={styles.container}>
  <SearchBar
    round
    lightTheme
    containerStyle={styles.search}
    ref="search"
    textInputRef="searchText"
    onChangeText={this.searchText.bind(this)}
    placeholder='Search by Truck Name...'
   />
   <TruckList getTruck={(truck) => this.setTruck(truck)} truckScreen={this.truckScreen} data={this.state.data}/>
</View>

then the TruckList.JS:

export default class TruckList extends Component {
    // rendering truck screen
    renderTruckScreen = (item) => {
        this.props.truckScreen();
        this.props.getTruck(item);
    }

    render() {
        return(
            <List style={styles.list}>
                <FlatList
                    data={this.props.data}
                    renderItem={({ item }) => (
                        <ListItem
                            roundAvatar
                            avatar={{uri: item.pic1}}
                            avatarStyle={styles.avatar}
                            title={item.name}
                            titleStyle={styles.title}
                            subtitle={
                                <View style={styles.subtitleView}>
                                    <Text style={styles.subtitleFood}>{item.food}</Text>
                                    <View style={styles.subtitleInfo}>
                                        <Icon 
                                            name="favorite"
                                            size={20}
                                            color={"#f44336"}
                                            style={styles.subtitleFavorite}
                                        />
                                        <Text style={styles.subtitleFavoriteText}>{item.favorited} favorited</Text>
                                    </View>
                                </View>
                            }
                            onPress={() => this.renderTruckScreen(item)}
                        />
                    )}
                    keyExtractor={(item) => item.uid}
                    ListFooterComponent={this.footer}
                />
            </List>
        )
      }
    }

I have tried a few other ways to no avail. Also the only solutions I have seen working for React Native are with ListView which will be depreciated in time. So I am trying to do this with the new FlatList Component.

Thanks for your help!

I came across this same issue today when trying to implement a filter / search function on the new FlatList component. This is how I managed to solve it:

By creating another item in the state of the parent component called noData, you can set that to true when there are no results that match your search and then render your FlatList conditionally.

My implementation is slightly different to yours, but if I had to adjust your code it would look something like this:

Searchtext function:

searchText = (e) => {
    let text = e.toLowerCase()
    let trucks = this.state.data
    let filteredName = trucks.filter((item) => {
      return item.name.toLowerCase().match(text)
    })
    if (!text || text === '') {
      this.setState({
        data: initial
      })
    } else if (!Array.isArray(filteredName) && !filteredName.length) {
      // set no data flag to true so as to render flatlist conditionally
      this.setState({
        noData: true
      })
    } else if (Array.isArray(filteredName)) {
      this.setState({
        noData: false,
        data: filteredName
      })
    }
  }

Then pass the noData bool to your TruckList component:

<TruckList getTruck={(truck) => this.setTruck(truck)} 
truckScreen={this.truckScreen} data={this.state.data} noData={this.state.noData}/>

Then render your FlatList in the TruckList component only if there are results:

<List style={styles.list}>
{this.props.noData ? <Text>NoData</Text> : <FlatList {...} />}         
</List>

That should then take care of handling user typing errors - as it will re-render the flatlist as soon as there are no results, and will remember the previous search state when you remove the typing error..

Let me know if that helps!

Search Filter with React Native on FlatList, I came across this same issue today when trying to implement a filter / search function on the new FlatList component. This is how I managed to solve it:. Search Bar filter is one of the most common way to filter large dynamic data. React Native Apply Real Time Search Bar Filter on FlatList JSON Data.

Update: This blog can help you better understand the searching in a FlatList.

FYI: If you have huge online data then you can also use algolia.

I adjusted the above code for me in order to make it work properly. The reason is that when user removes the last wrong character, code search this new string from a previous search list (state) which does not contain all objects, although it had to search from a full list available. So, I have two list now. One contains full list of objects and second contains only rendered list of objects which is changing upon search.

handleSearchInput(e){
    let text = e.toLowerCase()
    let fullList = this.state.fullListData;
    let filteredList = fullList.filter((item) => { // search from a full list, and not from a previous search results list
      if(item.guest.fullname.toLowerCase().match(text))
        return item;
    })
    if (!text || text === '') {
      this.setState({
        renderedListData: fullList,
        noData:false,
      })
    } else if (!filteredList.length) {
     // set no data flag to true so as to render flatlist conditionally
       this.setState({
         noData: true
       })
    }
    else if (Array.isArray(filteredList)) {
      this.setState({
        noData: false,
        renderedListData: filteredList
      })
    }
  }

Search Using Filter Data React Native, To make simple you can save data from server to json and get and set data using AsyncStorage. You just need once call data. Example Search Data React Native. Search Filter with React Native on FlatList. 3. Searching a FlatList in React Native. 1. FlatList does not output data - React Native. 2. How to highlight search

For a useful in-memory search you should keep initial data seperately.

I have more simple solution for this.

This solution for in-memory search on FlatList's data and uses it String.prototype​.includes() method to search substring.

You can find full source code of this component in this gist; https://gist.github.com/metehansenol/46d065b132dd8916159910d5e9586058

My initial state;

this.state = {
  searchText: "",
  data: [],
  filteredData: []
};

My SearchBar component (it comes from react-native-elements package);

<SearchBar
  round={true}
  lightTheme={true}
  placeholder="Search..."
  autoCapitalize='none'
  autoCorrect={false}
  onChangeText={this.search}
  value={this.state.searchText}
/>

My search method;

search = (searchText) => {
  this.setState({searchText: searchText});

  let filteredData = this.state.data.filter(function (item) {
    return item.description.includes(searchText);
  });

  this.setState({filteredData: filteredData});
};

And last my FlatList's DataSource expression;

<FlatList
  data={this.state.filteredData && this.state.filteredData.length > 0 ? this.state.filteredData : this.state.data}
  keyExtractor={(item) => `item-${item.id}`}
  renderItem={({item}) => <ListItem
    id={item.id}
    code={item.code}
    description={item.description}
  />}
/>

Happy coding...

Searching using Search Bar Filter in React Native List View, Example to Make Search Bar Filter for List View Data in React Native. Basically, We will make a React Native FlatList with real-time searching ability. Almost all the time, whenever you encounter a long list of data, you are also presented with the ability to search though that data so that you don’t get lost searching. Whatsapp country list with search React Native Searchable FlatList. I decided to build something to solve this problem. You can find the complete project repo here.

Here is my solution:

You need to have a backup of your data

this.state = {
    data: [],
    backup: []
}

on search method

search = txt => {
    let text = txt.toLowerCase()
    let tracks = this.state.backup
    let filterTracks = tracks.filter(item => {
    if(item.name.toLowerCase().match(text)) {
      return item
    }
  })
  this.setState({ data: filterTracks })
}

Explanation: when calling setState on your data it will changed to current state and cannot be changed again.

So backup data will handle to filter your data.

react-native-search-filter, React Native search component with filter function. Getting Started. Installation. Using npm : $ npm install react-  October 25, 2017 October 25, 2017React Native. Search Bar Filter is a real time filtering technique used in almost all Android and iOS applications to filter the JSON data in FlatList and ListView by typing text in TextInput component. It will filter the ListView according to user typed value and set the newly filter result again in ListView.

ref - https://medium.freecodecamp.org/how-to-build-a-react-native-flatlist-with-realtime-searching-ability-81ad100f6699

constructor(props) {
super(props);
this.state = {
  data: [],
  value: ""
};

this.arrayholder = [];
}

Next fetching data :-

_fetchdata = async () => {
const response = await fetch("https://randomuser.me/api?results=10");
const json = await response.json();
this.setState({ data: json.results });

this.arrayholder = json.results;
};

Next define searchFilterFunction :-

searchFilterFunction = text => {
this.setState({
  value: text
});


const newData = this.arrayholder.filter(item => {
  const itemData = item.email.toLowerCase();

  const textData = text.toLowerCase();

  return itemData.indexOf(textData) > -1;
});

this.setState({ data: newData });
};

rendering searchView:-

    <TextInput
      style={{ height: 40, borderColor: "gray", borderWidth: 1 }}
      onChangeText={text => this.searchFilterFunction(text)}
    />

Don't forget to import TextInput from "react-native";

FlatList, Filtering in FlatList, Spread Operators in React-Native , Contents in this project React Native Apply Real Time Search Bar Filter on FlatList JSON Data Android iOS Example Tutorial: 1. Open your  FlatLists are used for large quantities of scrollable content. They expose the underlying ScrollView, but add performance improvements.

React Native Apply Real Time Search Bar Filter on FlatList JSON , In React Native, FlatList is the common component that you will use to build the If you are calling API for the filter/search, you will have a lot of  Without setting this prop, FlatList would not know it needs to re-render any items because it is a PureComponent and the prop comparison will not show any changes. keyExtractor tells the list to use the ids for the react keys instead of the default key property.

#React Native Tutorial, Creating an InstantSearch app using React Native. - Native Display and format the search bar and results; Use pre-built UI components (widgets) to filter results The FlatList component is available since version v0.43 of React Native. React Native #5: React Navigation (Create Stack, Move Screen, Via Data and Organization project) - Duration: 14:29. Lirs Tech Tips 222 views

React Native Searchable FlatList with React Hooks – Big Cheese App, React Native FlatList Pagination. Here is an example of React Native FlatList Pagination to Load More Data dynamically – Infinite List. In this example, we will make a FlatList in which we will load the data in the form of pagination on a Click of a button.

Comments
  • what's the problem? Is it re-render not happening when user modifies the search text?
  • @Umesh the problem is that when the user mistypes the data is set to [] and then when they delete the mistype the data should be reset back to the last state of the search...just haven't figured out how that might work. Possibly setting previous state then calling it somehow?
  • When user mistypes, your result is empty [ ] but when user corrects it, will it not fetch the results again ? I guess onChange, you get the results every time.
  • It should fetch the results again, however, it does not. The mistype sets the data to [] but then when you delete the mistype the data is still []. When I console log during the typing what happens is after deleting the mistype it goes back to the else if(Array.isArray(filteredName)) however, there is no data for is to reset state to or something like that
  • May be you need to tweak your conditional order. My opinion is to search and store the results on every text search change, rather than relying on previous result set.
  • Do you guys have a github link for this solution ?
  • not working for me , when i am doing console of trucks.filter((item) => {console.log(item) } it is giving "message: "item is not defined""
  • in item.name.toLowerCase() it is giving error as well
  • If you console log the data that you are filtering do you get any data in there?
  • Is passing this.props.noData really required? Wouldn't it be cleaner just to check if(this.props.data)