How to get a clicked element in React?
Coming from jQuery, getting a clicked element was a breeze, but I'm having some issues with it in React. Basically, I've got a list, and I want to get a clicked list item (or its index) and animate it.
class TodoApp extends React.Component {
constructor(props)
{
super(props)
this.list_element = React.createRef()
this.state =
{
items: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn React", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
}
}
get_index ()
{
console.log(this.list_element.current.children)
}
render() {
return (
<ol ref={this.list_element}>
{this.state.items.map(item => (
<li onClick={ () => this.get_index()}>
<span>{item.text}</span>
</li>
))}
</ol>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
Live demo: https://jsfiddle.net/uo1L03ng/
However, I don't know how to get the clicked element in React. Should I use componentDidMount() instead and use the plain JavaScript to get the clicked element and future DOM manipulation?
What would be the best method?
Solution 1:
You can pass in parameters to the onClick
handler when mapping over your items
array. Array.prototype.map() also gives you access to the index of the element, hence, you can pass it to your doSomething()
method.
Here is a CodeSandbox to try it live!
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.list_element = React.createRef()
this.state = {
items: [
{ text: 'Learn JavaScript', done: false },
{ text: 'Learn React', done: false },
{ text: 'Play around in JSFiddle', done: true },
{ text: 'Build something awesome', done: true }
]
}
}
doSomething(item, index) {
console.log(item)
console.log(index)
}
render() {
return (
<ol>
{this.state.items.map((item, index) => (
<li key={item.text} onClick={() => this.doSomething(item, index)}>
<span>{item.text}</span>
</li>
))}
</ol>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector('#app'))
Solution 2:
You can pass item
as parameter in your onClick
function. And you should have key
prop for <li>
tag, if not, you'll get Warning: Each child in a list should have a unique "key" prop.
And use e.currentTarget
to interact with DOM element.
get_index(e, item) {
console.log(e.currentTarget); // <li>
console.log(item);
}
render() {
return (
<ol>
{this.state.items.map((item, index) => (
<li key={index} onClick={e => this.get_index(e, item)}>
<span>{item.text}</span>
</li>
))}
</ol>
);
}