I'm using reactstrap/bootstrap for an accordion functionality. I'm having trouble with my toggling and onclick. My state, function and render look like the following:
state = {
basicFeatures: [],
fuelEconomy: {},
upholsteryType: null,
category: 'Engine',
collapse: false,
active: false,
activeTab: 'capabilities',
};
toggle = active =>
this.setState({
collapse: !this.state.collapse,
active: !this.state.active,
});
const specsCatsR = this.props.specs.map((item, i) => {
return (
<React.Fragment>
<Col xs="12" key={i} className="border-bottom p-15">
<FontAwesomeIcon
icon={
this.state.active ? faMinusCircle : faPlusCircle
}
/>
<h5
className="collapse-header"
onClick={this.toggle.bind(this)}
>
{' '}
{item.category}{' '}
</h5>
<Collapse isOpen={this.state.active}>
<SpecsDetails
vehicle={this.props.vehicle}
values={item.values}
category={item.category}
/>
</Collapse>
</Col>
</React.Fragment>
);
});
It spits out a list of items. However, when I click on one item, they all open/toggle. How can I bind it to only open the one that is clicked?
If only one of your elements is supposed to be expanded at a time, I recommend storing the id of the currently expanded item in your state (here in active).
The toggle function will receive the id of the clicked element and then the onClick event arguments by preconfiguring it :
state = {
basicFeatures: [],
fuelEconomy: {},
upholsteryType: null,
category: 'Engine',
collapse: false,
active: null, //Active is not a boolean anymore
activeTab: 'capabilities',
};
toggle = id => ev => { //Add brackets here, you do not need to return the result of setState
this.setState({
collapse: !this.state.collapse,
active: id,
});
}
const specsCatsR = this.props.specs.map((item, i) =>
<React.Fragment>
<Col xs="12" key={i} className="border-bottom p-15">
<FontAwesomeIcon
icon={
this.state.active ? faMinusCircle : faPlusCircle
}
/>
<h5
className="collapse-header"
onClick={this.toggle(i)} // bind is not necessary since you are using an arrow function
>
{` ${item.category} `}
</h5>
<Collapse isOpen={this.state.active === i}> //If the index is the same as the active element id, it expands
<SpecsDetails
vehicle={this.props.vehicle}
values={item.values}
category={item.category}
/>
</Collapse>
</Col>
</React.Fragment>
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With