Dres
Dres

Reputation: 1509

Trying to change icon for a single list item

I'm trying to create an expandable list component. When I click on a list item, I want the icon to the right of it to change. Right now, when a list item is tapped, each icon is changed. I only want icon of that particular item to change. Been thinking about it for 20min and figured I'd reach out for help . Thanks!

import { List, ListItem } from 'react-native-elements';

export default class ExpandingList extends Component {

  constructor(props){
    super(props)

    this.state = {
      visibleItems: false
    }
  }

  toggleMenu(){
    this.setState({
      visibleItems: !this.state.visibleItems
    })
  };

  render() {
    const list = "list 1, list 2, list 3";

    return (
    <View>
      <List>
        {
        list.map((item, i) => (
          <ListItem
            onPress={ () => this.toggleMenu() }
            key={i}
            rightIcon={this.state.visibleItems ? iconRight : iconDown}
            title={item} />
        ))
        }
      </List
    </View
    )


  }
}

Upvotes: 0

Views: 2734

Answers (2)

Colin Ricardo
Colin Ricardo

Reputation: 17249

Here's a way to do it also:

import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  state = {
    visibleItem: 0
  };

  select = i => {
    this.setState({
      visibleItem: i
    });
  };

  render() {
    const items = [1, 2, 3, 4];

    return (
      <React.Fragment>
        {items.map((v, i) => {
          return (
            <div
              style={{ color: this.state.visibleItem === i ? "red" : "black" }}
              onClick={() => this.select(i)}
            >
              {v}
            </div>
          );
        })}
      </React.Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Working example here.

Upvotes: 1

Kevin Valentine
Kevin Valentine

Reputation: 41

You are doing a boolean value and all list items are looking at the same value. To achieve what you want you need to pass a unique value, in this situation i am using the index but ideally you will have a unique identifier besides the index.

Below should be able to acheive what you are looking for

import { List, ListItem } from 'react-native-elements';

export default class ExpandingList extends Component {

  constructor(props){
    super(props)

    this.state = {
      visibleItems: null
    }
  }

  toggleMenu(itemIndex){
    this.setState({
      visibleItems: itemIndex
    })
  };

  render() {
    const list = "list 1, list 2, list 3";

    return (
    <View>
      <List>
        {
        list.map((item, i) => (
          <ListItem
            onPress={ () => this.toggleMenu(i) }
            key={i}
            rightIcon={this.state.visibleItems === i ? iconRight : iconDown}
            title={item} />
        ))
        }
      </List
    </View
    )


  }
}

Note: I am assuming you have this rendering already but for other people. The list const is a comma separated string and string do not have a map function.

Also the code above does not take into account deselecting a list item that was already selected. That can be done by checking the value in the state and if it is the same reseting the value back to null.

Upvotes: 1

Related Questions