Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to change background of a touchableOpacity in iteration

I am looping an array , wrapping each item into touchableOpacity , attempting to change background Color of the clicked item on onPress event, my issue is that its changing the background color of the whole items , is there a way to change background Color to only the clicked item , here is my code

 return this.props.categes.map( (

            cat,i)=>

            <TouchableOpacity onPress = {() => this.changeBackground(i)} key = {i} style={{alignSelf : 'center', paddingLeft: 5, paddingRight : 7, paddingTop : 5, paddingBottom : 5, backgroundColor : this.state.background}}>
            <Text style={{color : '#838D8D'}}> {cat.name}</Text>
            </TouchableOpacity>

            )

  changeBackground(item){

        if(item)
        {
            this.setState({
                background: 'red'
            })
        }
    }
like image 412
dsaton22 Avatar asked Oct 23 '25 13:10

dsaton22


2 Answers

Hey I have made this example and I hope this solves your problem.Find working example here.(https://snack.expo.io/@shrutigarg/touchableopacity-background-change-onclick)

import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      categes: [
        { cat_id: '1', cat_name: 'abc', backgroundcolor: '#ED2525' },
        { cat_id: '2', cat_name: 'xyz', backgroundcolor: '#ED2525' },
        { cat_id: '3', cat_name: 'pqr', backgroundcolor: '#ED2525' },
        { cat_id: '4', cat_name: 'uvw', backgroundcolor: '#ED2525' },
        { cat_id: '5', cat_name: 'hij', backgroundcolor: '#ED2525' },
      ],
      change: false,
    };
  }

  changeBackground = item => {
    let categes = JSON.parse(JSON.stringify(this.state.categes));

    for (let x = 0; x < this.state.categes.length; x++) {
      if (this.state.categes[x].cat_id == item.cat_id) {
        categes[x].backgroundcolor = '#0000FF';

        this.setState({
          categes: categes,
        });
      } else {
        categes[x].backgroundcolor = '#ED2525';

        this.setState({
          categes: categes,
        });
      }
    }
  };
  render() {
    return (
      <View style={styles.container}>
        {this.state.categes.map((item, key) => (
          <TouchableOpacity
            style={{
              width: 200,
              height: 60,
              alignItems: 'center',
              justifyContent: 'center',
              margin: 10,
              backgroundColor: item.backgroundcolor,
            }}
            onPress={() => this.changeBackground(item)}>
            <Text style={{ color: '#FFFFFF' }}>
              {' '}
              {item.cat_name.toUpperCase()}
            </Text>
          </TouchableOpacity>
        ))}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
    alignItems: 'center',
  },
});
like image 137
shruti garg Avatar answered Oct 25 '25 02:10

shruti garg


Your code changes the color of all the items as it is unable to uniquely identify the item you clicked. The color you are changing is not associated with a particular item.

There are many ways to solve the problem. Here is one way where I create a separate component for each item, so each of these item's have their own state.

import React, { Component } from "react";
import { StyleSheet, TouchableOpacity, View, Text } from "react-native";

export default class App extends React.Component {
  render() {
    let listOfItems = [1, 2, 3, 4, 5, 6, 7, 8, 9];

    return (
      <View style={styles.container}>
        {listOfItems.map(e => {
          return <ToggleButton key={e + "i"} />;
        })}
      </View>
    );
  }
}

class ToggleButton extends Component {
  state = {
    on: false
  };

  render() {
    const { on } = this.state;

    return (
      <TouchableOpacity
        onPress={() => this.setState({ on: !this.state.on })}
        style={{ height: 50, width: 50, backgroundColor: on ? "green" : "red" }}
      >
        <Text>ITEM</Text>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center"
  }
});

listcolor

like image 22
10101010 Avatar answered Oct 25 '25 02:10

10101010