Reputation: 4106
I have 3 components built with React. They are:
How to manage the state of the clicked checkboxes. I would like Wrapper to know what checkboxes are checked.
class ListItem extends React.Component {
render(){
return (
<li>
<input type="checkbox" onChange={e => handleSelect(e.target.checked)} />
<label>Checkbox 1</label>
</li>
)
}
}
class List extends React.Component {
getList(){
const itemsList = this.props.list.map(
(item, index) => (
<ListItem key={index} item={item} />
)
)
return itemsList;
}
render(){
<ul>
{this.itemsList}
</ul>
}
}
class Wrapper extends React.Component {
const list = [
{"id": 1, "label": "label 1"},
{"id": 2, "label": "label 2"},
]
render(){
<List list={list} />
}
}
Upvotes: 1
Views: 778
Reputation: 1267
You should maintain the state of the list (and thus the checkboxes) in the Wrapper component instead, and pass that down to your List component.
Also, create the handler in the Wrapper component and pass that down too.
So your code becomes something like this:
class Wrapper extends React.Component {
constructor() {
this.state = [
{"id": 1, "label": "label 1", checked: false},
{"id": 2, "label": "label 2", checked: false}
]
}
handleChange(id, checked) {
this.setState((state) => {
return state.map(item => {
return {
...item,
checked: item.id === id ? checked : item.checked
}
});
});
}
render() {
<List list={this.state} onChange={this.handleChange} />
}
}
class List extends React.Component {
render(){
<ul>
{ this.props.list.map((item, index) => (
<ListItem key={index} item={item} handleChange={this.props.handleChange} />
)}
</ul>
}
}
class ListItem extends React.Component {
render(){
const { item } = this.props;
return (
<li>
<input type="checkbox" onChange={(e) => this.props.handleChange(item.id, e.target.checked)} />
<label>{ item.label } </label>
</li>
)
}
}
I didnt test this code, but I hope you get the gist of it. Maintain and change state in the top component, and use the lower components just to display and interact.
Upvotes: 1