Reputation: 3438
I have a few similar elements:
<div ref={this.ref1} onClick={this.handleClick} className="icon-wrapper"></div>
<div ref={this.ref2} onClick={this.handleClick} className="icon-wrapper"></div>
<div ref={this.ref3} onClick={this.handleClick} className="icon-wrapper"></div>
In my constructor, I declare these refs:
constructor(props) {
super(props);
this.ref1 = React.createRef();
this.ref2 = React.createRef();
this.ref3 = React.createRef();
}
I'm trying to pass these refs to their respective handleClick()
functions. Something like:
<div ref={this.ref1} onClick={this.handleClick(ref1)} className="icon-wrapper"></div>
or
<div ref={this.ref1} onClick={this.handleClick(this.ref)} className="icon-wrapper"></div>
And I'm trying to handle the ref in the handleClick
function like this:
handleClick = (ref) => {
console.log(ref);
}
And just as a ridiculously wild guess, I tried:
handleClick = () => {
console.log(this.ref.current);
}
That all seems dead wrong because onClick={this.handleClick(ref)}
would invoke the function immediately, which is not what is wanted from a click function.
How do you pass different refs to the same function so that the function knows who called it?
Upvotes: 1
Views: 490
Reputation: 8947
The answer to your question is to use a lambda method,
<div ref={this.ref1} onClick={() => this.handleClick(this.ref1)} className="icon-wrapper"></div>
<div ref={this.ref2} onClick={() => this.handleClick(this.ref2)} className="icon-wrapper"></div>
<div ref={this.ref3} onClick={() => this.handleClick(this.ref3)} className="icon-wrapper"></div>
But if what you want to do is to access the target that fired the event, you can use
handleClick = (event) => {
console.log(event.target);
}
<div onClick={this.handleClick} className="icon-wrapper"></div>
Edit: Here are some alternatives with better (marginal) performance.
handleClick1 = () => this.handleClick(this.ref1)
handleClick1 = this.handleClick.bind(this, this.ref1)
render() {
return (<div ref={this.ref1} onClick={this.handleClick1} className="icon-wrapper"></div>)
}
Upvotes: 1
Reputation: 25842
The main issue here is you are invoking the function immediately. Thats what applying ()
does to the end of a function. Instead you need to pass a callback function that needs to be invoked by the event. This is done by passing the function reference.
You can use bind
here if you need to pass a value. .bind
will return a new function to be invoked. null
as the first argument is for the this
context, null wont change its context assuming its already been bound to your class. If you need to bind this method you can just pass this
through instead of null
.
I would recommend passing something to map though instead of the whole ref, like so
<div ref={this.ref1} onClick={this.handleClick.bind(null, 'ref1')} className="icon-wrapper"></div>
then you would access like so
handleClick = (ref, event) => {
if (!this[ref]) return
console.log(this[ref].current);
}
Most use cases for passing a parameter to your function would be because you need a specific key. In this case it looks like you just want to access the element itself. You can get that from the event itself.
<div onClick={this.handleClick} className="icon-wrapper"></div>
handleClick = (event) => {
console.log(event.target);
}
Upvotes: 1