Sumit Shukla
Sumit Shukla

Reputation: 4504

Flatlist single item selection on tap

I am trying to change background color of a flatlist item as soon as user taps it. The problem here is that array is updated but background color is not changed for that selected item.

What I want to do is - As soon as flatlist item is clicked the background color for that row should change but it doesn't. Below is my code that I have tried.

import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, FlatList, TouchableOpacity } from 'react-native';
        
        let topData = [
            {
                id: '1',
                Name: 'Daily Oprations',
                selected: false,
            },
            {
                id: '2',
                Name: 'Financials',
                selected: false,
            },
            {
                id: '3',
                Name: 'Sharing',
                selected: false,
            },
            {
                id: '4',
                Name: 'Common Questions',
                selected: false,
            },
        ];
        
        const HelpDetails = () => {
            const [data, setData] = useState([]);
            useEffect(() => {
                setData(topData)
            }, []);
        
            const setSelectedIndex = (index) => {
                topData.map((e, i) => e.selected = (index == i))
                setData(topData)
            }
        
            const renderItem = ({ item, index }) => {
                console.log(item);
                return (
                    <TouchableOpacity onPress={() => setSelectedIndex(index)} style={[item.selected ? styles.greenbg : styles.whitebg, styles.storeInformationView]}>
        
                        <Text style={[item.selected ? styles.whitetext : null, styles.name]}>{item.Name}</Text>
                    </TouchableOpacity>
                );
            };
        
            return (
                <FlatList
                    data={data}
                    renderItem={renderItem}
                />
            );
        };
        
        export default HelpDetails;
        const styles = StyleSheet.create({
            greenbg: {
                backgroundColor: 'green'
            },
            whitebg: {
                backgroundColor: 'white',
            },
            storeInformationView: {
                //backgroundColor: APP_COLOR.GREEN_COLOR,
                borderRadius: 12,
                padding: 18,
                elevation: 15,
                marginHorizontal: 10,
                marginTop: 15,
        
                marginBottom: 17,
            },
            whitetext: {
                color: 'white'
            },
            name: {
                fontSize: 15,
                fontWeight: 'bold',
            },
        })
        
        const DATA = [
            {
                id: '1',
                Name: 'Daily Operations',
                selected: true,
            },
            {
                id: '2',
                Name: 'Financials',
                selected: false,
            },
            {
                id: '3',
                Name: 'Sharing',
                selected: false,
            },
            {
                id: '4',
                Name: 'Common Questions',
                selected: false,
            },
        ];

Upvotes: 0

Views: 2702

Answers (2)

user15028152
user15028152

Reputation:

I used TouchableOpacity then add the onPress event and pass the FaltList item.id to the onPress event.

   import {View, FlatList, Text, TouchableOpacity} from 'react-native';
     
const setSelectedIndex = (id) => {
        topData.map((item, index) => {
          if (index == id) {
            topData[index].selected = true;
          } else {
            topData[index].selected = false;
          }
        });
    
        setData([...topData]);
      };
    render() {
    
      return (
    
          <FlatList style={styles.list}
    
              data={this.state.data}
    
              renderItem={({item}) => (
    
                  <TouchableOpacity onPress={ () => this.actionOnRow(item.id)}>
    
                      <View>
                         <Text>ID: {item.id}</Text>
                         <Text>Title: {item.title}</Text>
                      </View>
    
                 </TouchableOpacity>
    
             )}
          /> 
       );
    }
    
    actionOnRow(item) {
       console.log('Selected Item :',item , item + item.id);
    }

Perform actions on the items by Item Id

Upvotes: 0

Vishal Dhanotiya
Vishal Dhanotiya

Reputation: 2638

You need to add a condition on setSelectedIndex. When you select any item from a list you need to set true on that selected key and false on all other keys

const setSelectedIndex = (id) => {
        
        topData.map((item, index) => {
          
          if (index == id) {
            topData[index].selected = true;
          } else {
            topData[index].selected = false;
          }
        });

    setData([...topData]);
  };

Please check the complete update code

import React, { useState, useEffect } from 'react';
    import {
      View,
      Text,
      StyleSheet,
      FlatList,
      TouchableOpacity,
    } from 'react-native';
    
    let topData = [
      {
        id: '1',
        Name: 'Daily Oprations',
        selected: false,
      },
      {
        id: '2',
        Name: 'Financials',
        selected: false,
      },
      {
        id: '3',
        Name: 'Sharing',
        selected: false,
      },
      {
        id: '4',
        Name: 'Common Questions',
        selected: false,
      },
    ];
    
    const HelpDetails = () => {
      const [data, setData] = useState([]);
      useEffect(() => {
        setData(topData);
      }, []);
    
      const setSelectedIndex = (id) => {
        // alert(JSON.stringify(topData))
        topData.map((item, index) => {
          // alert(JSON.stringify(index))
          if (index == id) {
            topData[index].selected = true;
          } else {
            topData[index].selected = false;
          }
          //topData[index].selected=true
        });
    
        setData([...topData]);
      };
    
      const renderItem = ({ item, index }) => {
        console.log(item);
        return (
          <TouchableOpacity
            onPress={() => setSelectedIndex(index)}
            style={[
              item.selected ? styles.greenbg : styles.whitebg,
              styles.storeInformationView,
            ]}>
            <Text style={[item.selected ? styles.whitetext : styles.name]}>
              {item.Name}
            </Text>
          </TouchableOpacity>
        );
      };
    
      return <FlatList data={data} renderItem={renderItem} />;
    };
    
    export default HelpDetails;
    const styles = StyleSheet.create({
      greenbg: {
        backgroundColor: 'green',
      },
      whitebg: {
        backgroundColor: 'white',
      },
      storeInformationView: {
        //backgroundColor: APP_COLOR.GREEN_COLOR,
        borderRadius: 12,
        padding: 18,
        elevation: 15,
        marginHorizontal: 10,
        marginTop: 15,
    
        marginBottom: 17,
      },
      whitetext: {
        color: 'white',
        fontWeight: 'bold',
      },
      name: {
        fontSize: 15,
        color: 'black',
        fontWeight: 'bold',
      },
    });

https://snack.expo.io/@vishal7008/flat-list-selection-issue

Upvotes: 1

Related Questions