Necmettin Sargın
Necmettin Sargın

Reputation: 87

How can I make my accordion items opens 1 at a time?

I'm trying to make accordion list without using any modules but I got stuck at this point. I have a expanded state which is false at the start. In onPress I'm making expanded true and {this.state.expanded && this piece of code makes view visible if expanded is true. I have used this accordion guide. I have more than 1 item but when I click one of them all of them opens. How do i solve this?

export default class FAQs extends Component {
    constructor(props) {
        super(props);
        this.state = {
            expanded: false,
            menu: [
                {
                    title: 'Non Veg Biryanis',
                    data: 'some data',
                },
                {
                    title: 'Pizzas',
                    data: 'soem data'
                },
            ]
        }
    }
    toggleExpand = () => {
        this.setState({ expanded: !this.state.expanded })
    }
    render() {
        return (
            <View style={container}>
                <FlatList
                    data={this.state.menu}
                    renderItem={({ item }) =>
                        <View style={card}>
                            <TouchableOpacity onPress={() => this.toggleExpand()}>
                                <View style={this.state.expanded ? cardHeaderBoxExpanded : cardHeaderBoxNotExpanded}>
                                    <View style={headerBox}>
                                        <Text style={cardHeader}>{item.title}</Text>
                                    </View>
                                </View>
                            </TouchableOpacity>
                            {this.state.expanded &&
                                <View style={cardTextBox}>
                                    <Text style={cardText}>
                                        {item.data}
                                    </Text>
                                </View>
                            }
                        </View>
                    }
                    keyExtractor={item => item.title}
                />
            </View>
        )
    }
}

Upvotes: 0

Views: 382

Answers (1)

Drea Zener
Drea Zener

Reputation: 323

You need to create a unique expanded state for each of your accordions.

Here is an expample below :

export default class FAQs extends React.PureComponent {


 static MENU = [
    {
      title: 'Non Veg Biryanis',
      data: 'some data',
    },
    {
      title: 'Pizzas',
      data: 'soem data',
    },
  ]

  constructor (props) {
    super(props);
    this.state = {
      menu: FAQs.MENU,
      expandedList: FAQs.MENU.map(() => ({ expanded: false })),
      refresh: false,
    };
  }

  toggleExpand = (i) => {
    this.state.expandedList[i].expanded = !this.state.expandedList[i].expanded;
    this.setState({
      refresh: !this.state.refresh,
    });
  }

  render () {
    return (
      <View style={container}>
        <FlatList
          data={this.state.menu}
          extraData={this.state.refresh}
          renderItem={({ item, index }) =>
            <View style={card}>
              <TouchableOpacity onPress={() => this.toggleExpand(index)}>
                <View style={this.state.expanded ? cardHeaderBoxExpanded : cardHeaderBoxNotExpanded}>
                  <View style={headerBox}>
                    <Text style={cardHeader}>{item.title}</Text>
                  </View>
                </View>
              </TouchableOpacity>
              {this.state.expandedList[index].expanded &&
              <View style={cardTextBox}>
                <Text style={cardText}>
                  {item.data}
                </Text>
              </View>
              }
            </View>
          }
          keyExtractor={item => item.title}
        />
      </View>
    );
  }
}

Upvotes: 1

Related Questions