How to highlight and multi-select items in a FlatList component

How to highlight and multi-select items in a FlatList component

How to highlight and multi-select items in a FlatList component

You’ve probably heard about Flatlist component if you are working in React native and handling lists of various client data and details either from the API or form fields. Basically, Flatlist is a core component designed for efficient display of vertically scrolling lists of changing data. It is a component which came into existence in React native after the 0.43 version, it replaced the ListView component and enhanced the ability of developers to deal with lists more easily.

What is Flatlist and How can we use it for displaying dynamic or static lists?

FlatList is a simple component introduced to remove the limitations of the ListView component. The basic props required to handle a Flatlist are data and renderItem. For simplicity, data is just a plain array, whereas renderItem renders this data array and provides the developer the metadata like index etc.

<FlatList   
  data={this.state.dataSource}
  renderItem={({item}) => <Text>{item.key}</Text>
 />

Using FlatList to display a list of Items:

If you are new to React Native, I would recommend you to go through this article here and try to learn the basic structure and come back again to understand this in a better way.

Next Step:

Here is the step by step guide on how to use FlatList to fetch data from a dummy API and use it to display a list of items with an image.

The first step is to import the Flatlist component from the react-native library.

import { FlatList } from "react-native";

Now as we have imported the component, it’s time to use this component in the render function.

<FlatList 
  data={this.state.dataSource}
  ItemSeparatorComponent={this.FlatListItemSeparator}
  renderItem={item => this.renderItem(item)} 
  keyExtractor={item => item.id.toString()}
/>

Points to Ponder:

  1. data prop takes data from {this.state.dataSource} and provides us with an array of objects.
  2. ItemSeparatorComponent helps in separating the list items when displayed in a list.
  3. the renderItem method is the most important part of a FlatList as it renders the array data in a manner that it can be developed as per data & design requirements.
  4. As we are dealing with an array here keyExtractor prop provides requires a unique key to handle the list item separately as required.
  5. There is one more essential prop called extraData which I will describe later in this article.

Now you have the basic understanding of how a Flatlist work. It’s time to implement this knowledge and logic in code. As we are using data from API I would be adding an indicator to display a loader till the data loads in the backend. It’s time to fetch the data and render it in a list. If you want to know more about fetching the data from the API you can read this article.

constructor(props) {
  super(props);
    this.state = {
     loading: false,
     dataSource: [],
    };
   }componentDidMount() {this.fetchData();}fetchData = () => {this.setState({loading: true});fetch("https://jsonplaceholder.typicode.com/photos")
.then(response => response.json())
.then(responseJson => {
 responseJson = responseJson.map(item => {
   item.isSelect = false;
   item.selectedClass = styles.list;
   return item;
 });
 this.setState({
  loading: false,
  dataSource: responseJson
 });
 }).catch(error => {this.setState({loading: false});
 });
};renderItem = data => 
 <TouchableOpacity style={[styles.list, data.item.selectedClass]
  onPress={() => this.selectItem(data)}>
  <Image source={{ uri: data.item.thumbnailUrl }}
    style={{ width: 40, height: 40, margin: 6 }}
  />
  <Text style={styles.lightText}{data.item.title.charAt(0).toUpperCase() + data.item.title.slice(1)}      </Text>
</TouchableOpacity>

So far we have handled the data and renderItem method and now it’s time to drill into remaining ones.

FlatListItemSeparator = () => <View style={styles.line} />;

You can provide the styling as per your design and change this style class. If you want to use my version of styling, I would share the code at the end of this article and you can get it from there. Now The key extractor method is basically for the unique id for the items and it’s better to use the exact code above to handle any warnings.

Now comes the fun part for what you have been waiting till now:

Any then and now, you must have come through a basic requirement where you need to select multiple items in a list and highlight it. Especially in marketing apps or todo list where you need to choose from hundreds of items in a list. Here is the code for selecting an item among various other items.

selectItem = data => {
  data.item.isSelect = !data.item.isSelect;
  data.item.selectedClass = data.item.isSelect
   ? styles.selected: styles.list;

const index = this.state.dataSource.findIndex(
   item => data.item.id === item.id
);this.state.dataSource[index] = data.item;
 this.setState({
   dataSource: this.state.dataSource
 });
};

What we have here is a screen with selected items highlighted in a bright color whereas the other items in the list are set to have default styling. In order to understand the logic more clearly let’s look into the fetch component

.then(responseJson => {
 responseJson = responseJson.map(item => {
   item.isSelect = false;
   item.selectedClass = styles.list;
   return item;
 });
In he

In here we have assigned item.isSelect as false and selectedClass is assigned a default style class called list, the reason behind doing this is, Now each and every item in our list will be having these two propsinside them which can be used to fetch the item uniquely and manipulate it. Now in our selectItem()function, we added a rendering condition as follows:

selectItem = data => {
  data.item.isSelect = !data.item.isSelect;
  data.item.selectedClass = data.item.isSelect
   ? styles.selected: styles.list;

Next, when we click on any item in our FlatList the selectItem function gets rendered and it changes the styling of that item to a highlighted class such as selected class here and rest of the list items have default styling from the class list.

Here comes the important part:

FlatList has a prop called extraData and what it does basically is it re-renders the FlatList whenever there is any change using state. This feature re-renders our selectItem and renderItem function and highlights the selected items otherwise only one item will be selected as the FlatList is rendered at the beginning of the component loading and remains in the same state even if the state and data change state.

extraData

A marker property for telling the list to re-render (since it implements PureComponent).

extraData={this.state}

All you have to do is add it in the FlatList component and we are done with highlighting multiple items in a list.

Hope this article is helpful to you and enhances your ability to deal with this requirement easily. I am sharing full code snippet here if you want to use it as an example.

Full code here:

import React from "react";
import{StyleSheet,View,ActivityIndicator,FlatList,Text,TouchableOpacity,Image} from "react-native";
import { Icon } from "react-native-elements";
import { enText } from "../lang/en"export default class Store extends React.Component { constructor(props) {
 super(props)
 this.state = {
   loading: false,
   dataSource: [],
  };
}componentDidMount() {this.fetchData();}fetchData = () => {this.setState({loading: true});fetch("https://jsonplaceholder.typicode.com/photos")
.then(response => response.json())
.then(responseJson => {
 responseJson = responseJson.map(item => {
   item.isSelect = false;
   item.selectedClass = styles.list;
 return item;
});this.setState({
 loading: false,
 dataSource: responseJson,
});
}).catch(error => {this.setState({loading: false});
});
};FlatListItemSeparator = () => <View style={styles.line} />;selectItem = data => {
data.item.isSelect = !data.item.isSelect;
data.item.selectedClass = data.item.isSelect?
             styles.selected: styles.list;
const index = this.state.dataSource.findIndex(
 item => data.item.id === item.id
);
this.state.dataSource[index] = data.item;
this.setState({
 dataSource: this.state.dataSource,
});
};goToStore = () =>this.props.navigation.navigate("Expenses", {selected: this.state.selected,});renderItem = data =>
 <TouchableOpacity
   style={[styles.list, data.item.selectedClass]}      
   onPress={() => this.selectItem(data)}
 >
 <Image
   source={{ uri: data.item.thumbnailUrl }}
   style={{ width: 40, height: 40, margin: 6 }}
 />
 <Text style={styles.lightText}>  {data.item.title.charAt(0).toUpperCase() + data.item.title.slice(1)}  </Text>
</TouchableOpacity>render() {
const itemNumber = this.state.dataSource.filter(item => item.isSelect).length;if (this.state.loading) {return (
<View style={styles.loader}>
<ActivityIndicator size="large" color="purple" />
</View>
);
}
return (
  <View style={styles.container}>
  <Text style={styles.title}>{enText.productsAvailable}</Text>
  <FlatList
    data={this.state.dataSource}
   ItemSeparatorComponent={this.FlatListItemSeparator}
   renderItem={item => this.renderItem(item)}
   keyExtractor={item => item.id.toString()}
   extraData={this.state}
  />
 <View style={styles.numberBox}>
 <Text style={styles.number}>{itemNumber}</Text>
 </View>
 <TouchableOpacity style={styles.icon}>
   <View>
     <Icon
       raised
       name="shopping-cart"
       type="font-awesome"
       color="#e3e3e3" 
       size={30} 
       onPress={() => this.goToStore()}
       containerStyle={{ backgroundColor: "#FA7B5F" }}
     />
   </View>
</TouchableOpacity>
</View>
);}}const styles = StyleSheet.create({
container: {
 flex: 1,
 backgroundColor: "#192338",
 paddingVertical: 50,
 position: "relative"
},title: {
 fontSize: 20,
 color: "#fff",
 textAlign: "center",
 marginBottom: 10
},loader: {
 flex: 1, 
 justifyContent: "center",
 alignItems: "center",
 backgroundColor: "#fff"
},list: {
 paddingVertical: 5,
 margin: 3,
 flexDirection: "row",
 backgroundColor: "#192338",
 justifyContent: "flex-start",
 alignItems: "center",
 zIndex: -1
},lightText: {
 color: "#f7f7f7",
 width: 200,
 paddingLeft: 15,
 fontSize: 12
},line: {
 height: 0.5,
 width: "100%",
 backgroundColor:"rgba(255,255,255,0.5)"
},icon: {
 position: "absolute",  
 bottom: 20,
 width: "100%", 
 left: 290, 
 zIndex: 1
},numberBox: {
 position: "absolute",
 bottom: 75,
 width: 30,
 height: 30,
 borderRadius: 15,  
 left: 330,
 zIndex: 3,
 backgroundColor: "#e3e3e3",
 justifyContent: "center",
 alignItems: "center"
},number: {fontSize: 14,color: "#000"},selected: {backgroundColor: "#FA7B5F"},});

30s ad

Master ReactJS: Learn React JS from Scratch

Learn ReactJS: Code Like A Facebook Developer

ReactJS Course: Learn JavaScript Library Used by Facebook&IG

React: Learn ReactJS Fundamentals for Front-End Developers

React From The Ground Up

react-native reactjs

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How native is React Native? | React Native vs Native App Development

Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.

Hire Dedicated React Native Developer

Have you ever thought of having your own app that runs smoothly over multiple platforms? React Native is an open-source cross-platform mobile application framework which is a great option to create mobile apps for both Android and iOS. **[Hire...

Build a simple React Native Pokemon app with React-Navigation

As we start learning new technologies we want to start building something or work on a simple project to get a better understanding of the technology.

Hire Dedicated React Native Developer in India | React Native Development

Hire dedicated React Native developers for your next project. As the top react native development company we offer you the best service as per your business needs.

Which is the best React Native app development company in New York?

Hire top react native app development company in New York to build and develop custom react native mobile apps for Android & iOS with the latest features.