Home > Net >  React Native: How do I switch the state of only one item in FlatList?
React Native: How do I switch the state of only one item in FlatList?

Time:10-11

what happens is the following fact: I want to add "switch/toggle" next to id 2.3 and 4 items, but it's getting on all items on the flatlist. I used "import SwitchSelector from "react-native-switch-selector"; " Can anyone who understands flatlist help me? I will be very happy and grateful I'm not getting it at all, and I'm thinking of redoing my code because of this problem

Settings.js

import { SafeAreaView,Text, View, FlatList,
TouchableOpacity, StyleSheet, Image} from 'react-native';
import SwitchSelector from "react-native-switch-selector";
import React, {useState} from 'react'
    
 
    
    const Settings = () => {
      const [data, setdata] = useState(DATA);
      const [isRender, setisRender] = useState(false);

         const DATA = [
        {id: 1, text: 'Perfil', image: require('../../assets/images/user.png')},
        {id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png')},
        {id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png')},
        {id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png')},
        //{id: 5, text: 'Logout'},
    ]
    
    
      const renderItem = ({item}) => {
        return(
        <TouchableOpacity 
        style= {styles.item}
        >
        <View style={ styles.avatarContainer }>
           <Image source={ item.image } style={ styles.avatar } />
        </View>
        <View>
           <Text style={styles.text}>{item.text}</Text>
        </View>
    
        </TouchableOpacity>
        )
      }
      
    
      
    
      return (
      <SafeAreaView style={styles.container}>
        <FlatList
        data={DATA}
        keyExtractor={(item) => item.id.toString()}
        renderItem={renderItem}
        extraData={isRender}
        />
        
        
      </SafeAreaView>
      );
    };
    
    const styles = StyleSheet.create({
        container: {
        flex: 1,
        marginTop: 20
        //marginHorizontal: 21

        },
        item:{
        borderBottomWidth: 1,
        borderBottomColor: '#808080',
        alignItems: 'flex-start',
        flexDirection: 'row',
  
        },
        avatarContainer: {        
            backgroundColor: 'transparent',
            //borderRadius: 100,
            height: 30,
            width: 30,
            justifyContent: 'center',
            alignItems: 'center',
                
          },
          
          avatar: {
            height: 25,
            width: 25,
            bottom: -25,
            marginLeft: 30
          },
        text:{
            marginVertical: 30,
            fontSize: 20,
            fontWeight: 'bold',
            marginLeft: 30,
            marginBottom: 10,
            bottom: 5
            

        },

        
       
    });
    
    export default Settings;

CodePudding user response:

You could try adding a boolean property to each item in DATA. You could then conditionally show a <SwitchSelector /> in renderItem based on that property.

For example, below I added the property showSwitch and used a ternary expression to conditionally show a <SwitchSelector /> in renderItem:

const DATA = [
{id: 1, text: 'Perfil', image: require('../../assets/images/user.png'), showSwitch: false},
{id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png'), showSwitch: true},
{id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png'), showSwitch: true},
{id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png'), showSwitch: true},
//{id: 5, text: 'Logout'}
]

...

const renderItem = ({ item }) => {
  return (
    <TouchableOpacity style={styles.item}>
      <View style={styles.avatarContainer}>
        <Image source={item.image} style={styles.avatar} />
      </View>
      <View>
        <Text style={styles.text}>{item.text}</Text>
      </View>
      {item.showSwitch ? <SwitchSelector /> : null}
    </TouchableOpacity>
  );
};

CodePudding user response:

This works from me: import { SafeAreaView,Text, View, FlatList, TouchableOpacity, StyleSheet, Image, Switch} from 'react-native';

import React, {useState, useEffect} from 'react'; import {TouchID} from 'react-native-touch-id';

const Settings = () => {
  const [data, setdata] = useState(DATA);
  const [isRender, setisRender] = useState(false);

  const DATA = [
    {id: 1, text: 'Perfil', image: require('../../assets/images/user.png'), switch: false},
    {id: 2, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png'), switch: true},
    {id: 3, text: 'TouchId', image: require('../../assets/images/fingerprint.png'), switch: true},
    {id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png'), switch: true},
    //{id: 5, text: 'Logout'}
    ]


  const renderItem = ({item}) => {
    return(
    <TouchableOpacity 
    style= {styles.item}
    >
    <View style={ styles.avatarContainer }>
       <Image source={ item.image } style={ styles.avatar } />
    </View>
    <View>
       <Text style={styles.text}>{item.text}</Text>
    </View>
    {item.switch ? <Switch /> : null}
    </TouchableOpacity>
    )
  }
  

  return (
  <SafeAreaView style={styles.container}>
    <FlatList
    data={DATA}
    keyExtractor={(item) => item.id.toString()}
    renderItem={renderItem}
    extraData={isRender}
    />
    
    
  </SafeAreaView>
  );
};

const styles = StyleSheet.create({
    container: {
    flex: 1,
    marginTop: 20
    //marginHorizontal: 21

    },
    item:{
    borderBottomWidth: 1,
    borderBottomColor: '#808080',
    alignItems: 'flex-start',
    flexDirection: 'row',

    },
    avatarContainer: {        
        backgroundColor: 'transparent',
        //borderRadius: 100,
        height: 30,
        width: 30,
        justifyContent: 'center',
        alignItems: 'center',
            
      },
      
      avatar: {
        height: 25,
        width: 25,
        bottom: -25,
        marginLeft: 30
      },
    text:{
        marginVertical: 30,
        fontSize: 20,
        fontWeight: 'bold',
        marginLeft: 30,
        marginBottom: 10,
        bottom: 5
        

    },

    
   
});

export default Settings;
  • Related