I have a <ul>
Component wrapping some <li>
Components. I want to avoid adding an onClick
handler to each li
and instead use a single handler on the ul
and capture the bubbled events.
What is the correct way of determining / assigning the clicked Component from the bubbled event?
class ListItemComponent extends React.Component {
public render() {
return (
<li>Foo</li>
)
}
}
class ListComponent extends React.Component {
private handleClick(event) {
const target = event.target;
// Determine clicked component, or index etc … ?
}
public render() {
const items = this.props.items.map((x, i) => {
<ListItemComponent active=“false” key={i} />
})
return (
<ul onClick={this.handleClick} />
{ items }
</ul>
)
}
}
My solution was to add a data-index
attribute to each child which can be used to identify the component.
This avoids adding multiple event listeners while also avoiding the overhead of multiple ref
callbacks to obtain the child DOM elements:
class ListItemComponent extends React.Component {
public render() {
return (
<li data-index={this.props.index}>Foo</li>
)
}
}
class ListComponent extends React.Component {
private handleClick(event) {
const activeIndex = event.target.getAttribute('data-index');
this.setState({ activeIndex });
}
public render() {
const active = this.state.activeIndex;
const items = this.props.items.map((x, i) => {
<ListItemComponent active={i === active} key={i} index={i} />
})
return (
<ul onClick={this.handleClick} />
{ items }
</ul>
)
}
}