Reputation: 271
I have some data in arrays. I am getting it by using map, as you see in the below example. Also, i pass that into the button. Now, if, i select a button, it will get selected. But, if i select the next button, the previous button will get unselected and the current button will get selected. I don't want it to happen. I want to select multi buttons, if it all get clicked.
Thanks in advance.
Below is the Solution
import React, { Component } from 'react';
const BUTTONS = [
{id:0, title:'button1'},
{id:1, title:'button2'},
{id:2, title:'button3'}
]
class Map extends Component {
constructor(props){
super(props);
this.state = {
values: []
}
}
handleButton = button => {
let tmp = this.state.values;
if (this.state.values.includes(button)) {
this.setState({
values: this.state.values.filter(el => el !== button)
})
} else {
tmp.push(button);
this.setState({
values: tmp
})
}
}
render () {
return (
<div>
{BUTTONS.map(bt=>(
<button
key={bt.id}
onClick={()=>this.handleButton(bt.id)}
className={this.state.values.includes(bt.id) ? "buttonPressed" : "button"}>
{bt.title}
</button>
))}
</div>
);
}
}
export default Map;
Upvotes: 1
Views: 5933
Reputation: 6159
The reason your button is getting deselected is because you're overwriting this.state.value
every time you click a button.
If you want multiple selections, you'll need to hold all of the selected items in the state, as an array, and then when rendering, check if the button id is included in that array.
Something like:
import React, { Component } from 'react';
const BUTTONS = [
{id:0, title:'button1'},
{id:1, title:'button2'},
{id:2, title:'button3'}
]
class Map extends Component {
constructor(props){
super(props);
this.state = {
selectedValues: []
}
}
handleButton = buttonId => {
let newSelectedValues = this.state.selectedValues;
newSelectedValues.push(buttonId);
this.setState({
selectedValues: newSelectedValues
})
}
render () {
return (
<div>
{BUTTONS.map(bt => (
<button
key={bt.id}
onClick={()=>this.handleButton(bt.id)}
className={this.state.selectedValues.includes(bt.id) ? "buttonPressed" : "button"}>
{bt.title}
</button>
))}
</div>
);
}
}
export default Map;
Upvotes: 1
Reputation: 10294
Selecting multiple buttons
you'd better use the state
as an array
.
this.state = {
values: []
}
and you can push
items.
let tmp = this.state.values;
tmp.push(button);
this.setState({
values: tmp
});
in render()
you have to check state.values
has bt.id
className={this.state.values.includes(bt.id) ? "buttonPressed" : "button"
Toggling multiple buttons
you can check in handleButton()
whether that selected button is already selected
handleButton = button => {
if (this.state.values.includes(button)) {
this.setState({
values: this.state.values.filter(el => el !== button)
})
}
const BUTTONS = [
{ id: 0, title: 'button1' },
{ id: 1, title: 'button2' },
{ id: 2, title: 'button3' }
]
class Map extends React.Component {
constructor(props) {
super(props);
this.state = {
values: []
}
}
handleButton = button => {
let tmp = this.state.values;
if (this.state.values.includes(button)) {
this.setState({
values: this.state.values.filter(el => el !== button)
})
} else {
tmp.push(button);
this.setState({
values: tmp
})
}
}
render() {
return (
<div>
{BUTTONS.map(bt => (
<button
key={bt.id}
onClick={() => this.handleButton(bt.id)}
className={this.state.values.includes(bt.id) ? "buttonPressed" : "button"}>
{bt.title}
</button>
))}
</div>
);
}
}
export default Map;
Upvotes: 1
Reputation: 53
if you need multiple selections you need an array:
this.state = {
values:[]
}
and push it on each clicks Correct way to push into state array
Upvotes: 0