Reputation: 119
I'm trying to update each item in the state by clicking a button. The initial state is FALSE (isSelected) for each item, if users do a onClick event on the button class div it should update the state (isSelected) of the current item to TRUE, but I'm not figuring out how to accomplish this.
EDITED: It should update only one item per click for example if I hit the button for ID: 1
of firsItem
it should change isSelected
state to true
only for ID: 1
This is an example of my code (how a I think it should be)
import React, { Component } from 'react'
export default class List extends Component {
constructor(props) {
super(props);
this.state = {
listItems: [{
name: 'firstItem',
itemOptionSelector: [{
id: 1,
isSelected: false
},
{
id: 2,
isSelected: false
},
{
id: 3,
isSelected: false
},
]
},
{
name: 'secondItem',
itemOptionSelector: [{
id: 1,
isSelected: false
},
{
id: 2,
isSelected: false
},
{
id: 3,
isSelected: false
},
]
}
]
}
}
selectItemClickHandler = () => {
this.setState({
listItems: [{itemOptionSelector: [{isSelected: true}]}]
})
}
render() {
const {listItems} = this.state
return (
<div>
{listItems.map(item => {
<div className="button" onClick={this.selectItemClickHandler}>{item.name}</div>
})}
</div>
)
}
}
Upvotes: 0
Views: 919
Reputation: 5854
Please check this complete example. Basically you had issue in setting state on click handler.
selectItemClickHandler = () => {
this.setState({
listItems: [{itemOptionSelector: [{isSelected: true}]}]
})
}
Updated code of selectItemClickHandler
should be:
selectItemClickHandler = (event, index) => {
this.setState(prevState => {
const list = [];
prevState.listItems.map((item, i) => {
if (i === index) {
item.itemOptionSelector.map(selector => {
selector.isSelected = true
})
}
list.push(item);
});
return {
listItems: list
};
});
};
Here is the complete example where I have changed the above code
import React, {Component} from 'react'
export default class ListExample extends Component {
constructor(props) {
super(props);
this.state = {
listItems: [
{
name: 'firstItem',
itemOptionSelector: [
{id: 1,isSelected: false},
{id: 2,isSelected: false},
{id: 3,isSelected: false},
]
},
{
name: 'secondItem',
itemOptionSelector: [
{id: 1,isSelected: false},
{id: 2,isSelected: false},
{id: 3,isSelected: false},
]
}
]
}
}
selectItemClickHandler = (event, index) => {
this.setState(prevState => {
const list = [];
prevState.listItems.map((item, i) => {
if (i === index) {
item.itemOptionSelector.map(selector => {
selector.isSelected = true
})
}
list.push(item);
});
return {
listItems: list
};
});
};
render() {
const {listItems} = this.state;
return (
<div>
{listItems.map((item, index) => {
return <div key={index} className="button" onClick={(event) => {
this.selectItemClickHandler(event, index)
}}>{item.name}</div>
})}
<button onClick={()=>{ console.log(this.state, 'current state') }}>Show State in Console</button>
</div>
)
}
}
Upvotes: 1
Reputation: 1316
I'm going to post an example because it's not clear what you want to update.
Let's say this is your state.
state = {
items: [
{
id: 1,
isSelected: false,
},
{
id: 2,
isSelected: false,
},
{
id: 3,
isSelected: false,
}
]
};
And this is how you render your items.
<ul>
{this.state.items.map((item, index) => (
<li key={item.id} onClick={this.handleToggle(index)}>
{item.id} {item.isSelected + ""}
</li>
))}
</ul>
Then, your handler needs to look like this.
// pay attention to the handler which creates a closure
handleToggle = index => () => {
const items = [...this.state.items];
items[index].isSelected = !items[index].isSelected;
this.setState({ items });
};
Upvotes: 1
Reputation: 9128
First of all, it's not clear what you are trying to do. You're not rendering your "sub-items" (or options), so there's no way currently to know which option should be changed to the selected state.
Generally, you update an array state like this:
state = {
items: [
{ isSelected: false, name: 'first' },
{ isSelected: false, name: 'second' },
{ isSelected: false, name: 'third' },
]
};
// ...
handleItemClick = (item, index) => {
const items = this.state.items.slice();
items[index] = { ...item, isSelected: !item.isSelected };
this.setState({ items });
};
render() {
return this.state.items.map((item, index) =>
<div onClick={() => this.handleItemClick(item, index)}>{item.name}</div>);
}
Upvotes: 1