Highlight a selected item in React-Native FlatList

You can do something like:

  1. For the renderItem, use something like a TouchableOpacity with an onPress event passing the index or id of the renderedItem;

  2. Function to add the selected item to a state:

    handleSelection = (id) => {
       var selectedId = this.state.selectedId
    
       if(selectedId === id)
         this.setState({selectedItem: null})
       else 
         this.setState({selectedItem: id})
    }
    
    handleSelectionMultiple = (id) => {
       var selectedIds = [...this.state.selectedIds] // clone state
    
       if(selectedIds.includes(id))
         selectedIds = selectedIds.filter(_id => _id !== id)
       else 
         selectedIds.push(id)
    
       this.setState({selectedIds})
    }
    
  3. FlatList:

    <FlatList
      data={data}
      extraData={
        this.state.selectedId     // for single item
        this.state.selectedIds    // for multiple items
      }
      renderItem={(item) => 
         <TouchableOpacity 
    
           // for single item
           onPress={() => this.handleSelection(item.id)}
           style={item.id === this.state.selectedId ? styles.selected : null} 
    
           // for multiple items
           onPress={() => this.handleSelectionMultiple(item.id)}
           style={this.state.selectedIds.includes(item.id) ? styles.selected : null} 
         >
            <Text>{item.name}</Text>
         </TouchableOpacity>
      }
    

    />

  4. Make a style for the selected item and that's it!


In place of this.state.selectedItem and setting with/checking for a rowItem.id.value, I would recommend using a Map object with key:value pairs as shown in the RN FlatList docs example: https://facebook.github.io/react-native/docs/flatlist.html. Take a look at the js Map docs as well: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map.

The extraData prop recommended by @j.I-V will ensure re-rendering occurs when this.state.selected changes on selection.

Your onPressAction will obviously change a bit from example below depending on if you want to limit the number of selections at any given time or not allow user to toggle selection, etc.

Additionally, though not necessary by any means, I like to use another class or pure component for the renderItem component; ends up looking something like the following:

export default class BasicFlatList extends Component {
  state = {
    otherStateStuff: ...,
    selected: (new Map(): Map<string, boolean>) //iterable object with string:boolean key:value pairs
  }

  onPressAction = (key: string) => {
    this.setState((state) => {
      //create new Map object, maintaining state immutability
      const selected = new Map(state.selected);
      //remove key if selected, add key if not selected
      this.state.selected.has(key) ? selected.delete(key) : selected.set(key, !selected.get(key));
      return {selected};
    });
  }

  renderRow = (item) => {
    return (
        <RowItem
          {...otherProps}
          item={item}
          onPressItem={this.onPressAction}
          selected={!!this.state.selected.get(item.key)} />
    );
  }

  render() {
    return(
      <FlatList style={styles.container}
        data={this.state.data}
        renderItem={({ item }) => (
          this.renderRow(item)
        )}
        extraData={this.state}
      />
    );
  }
}


class RowItem extends Component {
  render(){
    //render styles and components conditionally using this.props.selected ? _ : _
    
    return (
      <TouchableOpacity onPress={this.props.onPressItem}>
        ...
      </TouchableOpacity>
    )
  }
}

You should pass an extraData prop to your FlatList so that it will rerender your items based on your selection

Here :

<FlatList style={styles.container}
    data={this.state.data}
    extraData={this.state.selectedItem}
    renderItem={({ item }) => (
      this.renderRow(item)
    )}
 />

Source : https://facebook.github.io/react-native/docs/flatlist

Make sure that everything your renderItem function depends on is passed as a prop (e.g. extraData) that is not === after updates, otherwise your UI may not update on changes