3

I want to call two functions passes via props on click. Note that both of them need arguments of their own. After a bit of searching on Stack Overflow, I found this solution:

onclick={()=>{ f1(); f2() }}

So I implemented mine as follows:

onClick={() => {f1(arg); f2.bind(this, arg)}}

But the second function never gets called. Can anyone please explain why this isn't working? I'm assuming its some binding issue?

f1 is in the parent component:

f1(arg, event)
{
        event.preventDefault();
        // so on...
}

f2 is also in the parent argument as follows:

f2(arg)
{
     // do something with the argument 
}

They are getting passed to the child component

 render()
    {
            const { f2, arg, f1 } = this.props;
    
            return(
                <button onClick={() => {f2(arg); f1.call(this, arg)}}>
)
    }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
mikasa
  • 783
  • 1
  • 11
  • 29

4 Answers4

4

Second function isn't working, because you not actually calling function using bind, you just binding scope for future function calls. If you want to call function with specified scope, use call or apply

More about them: https://stackoverflow.com/a/15455043/5709697

EDIT

For your case you can call second function like so:

onClick={(e) => {f1(e); f2.call(this, e)}}

Link to sandbox: https://codesandbox.io/s/509o1lxjp

Azamat Zorkanov
  • 779
  • 1
  • 4
  • 9
  • How will I call the function here after binding it? – mikasa Jul 20 '18 at 05:34
  • I also need to pass argument to f2. So will that be implemented like f2.call(this,e,arg) ? – mikasa Jul 20 '18 at 05:47
  • Gives 'TypeError: event.preventDefault is not a function'. Why do we have to pass event when we've already passed this? – mikasa Jul 20 '18 at 05:52
  • 1
    Actually, as @Mayank Shukla said, there are no need to call second function using call(or maybe the need exist, depends on situation). I've provided sandbox, where that funtionality, which you asking for works. Maybe you can edit with your code, and show us, what's going on? – Azamat Zorkanov Jul 20 '18 at 06:03
  • My answer is updated. Can you please share the sandbox? – mikasa Jul 20 '18 at 06:06
  • It works! THANK YOU. Can you please explain why it works though? Why do we need to pass event when we have already bounded it to 'this'? – mikasa Jul 20 '18 at 06:31
2

Try this way

 onClick={(arg)=>{ this.f1(arg); this.f2(this, arg) }}

Or make a separate function call as below.

onClick={(arg)=>{ this.f1(arg) }}

f1(values){
this.f2(values);
}
Krina Soni
  • 870
  • 6
  • 14
1

You can call both methods as

onClick={() =>{ this.f1(arg);this.f2(arg)}}
Harikrishnan
  • 1,097
  • 8
  • 13
1

Because you are not calling the second method just creating it using bind.

When you used () => {} with onClik, context will be maintained by arrow function, you don't need to bind those two functions after that.

Write it like this:

onClick={(e) => {
   this.f1(e, arg1, arg2, arg3);     // use f1, if function is defined outside of class
   this.f2(e, arg2)
}}

f1 (e, arg1, arg2, arg3) {
   e.preventDefault();
   console.log(arg1, arg2, arg3)
}

f2 (e, arg2) {
   e.preventDefault();
   console.log(arg2)
}

Check MDN Doc: The bind() method creates a new function.


Check these answers for more details about binding:

Use of the JavaScript 'bind' method

Why is JavaScript bind() necessary?

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • The second function has got the event property so I need to pass this as an argument. Doing what you suggested gave me the error: '× TypeError: Cannot read property 'preventDefault' of undefined' – mikasa Jul 20 '18 at 05:21
  • that means you forgot to pass the event object to functions, check the updated answer. – Mayank Shukla Jul 20 '18 at 05:23
  • if you don't want to use the event in any function then don't pass as an argument, lets say you want only in 2nd function, then remove from 1st function, like this: `this.f1(arg1, arg2, arg3); ` and remove from function argument also. – Mayank Shukla Jul 20 '18 at 05:26
  • TypeError: _this2.f1 is not a function – mikasa Jul 20 '18 at 05:40
  • @eren555 can you show the full code, where you have defined the f1 and f2 and the element on which you are using the click handler? – Mayank Shukla Jul 20 '18 at 05:47