-2

I have an event handler which calls a fat arrow function to run a method.

import React, { Component } from 'react';

class App extends Component {
  sayHi = msg => {
    console.log(msg);
  };

  render() {
    return (
      <div>
        <button onClick={() => this.sayHi('Hi')}>Console Hi!</button>
      </div>
    );
  }
}

export default App;

I´m learning about contexts and bind() and, I want to convert this example to bind this. My problem is with the parameter that I´m passing when the fat arrow function executes the method, aka, 'Hi'

Is there a way to keep something like this...

<button onClick={this.sayHi('Hi')}>Console Hi!</button>

I tried different ways without good results. Mostly, focused on

  constructor(props) {
    super(props);
    this.sayHi = this.sayHi.bind(this);
  }

  sayHi = () => {
    console.log(msg);
  };

And yes... I don´t want to move the 'Hi' to the method or constructor. I´m trying to learn and understand. I will appreciate any kind of help or orientation.

Peter
  • 2,004
  • 2
  • 24
  • 57
  • You shouldn't need `bind` (or even the constructor) if you're using arrow functions. See https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56 Arguably this is a duplicate of https://stackoverflow.com/questions/29810914/react-js-onclick-cant-pass-value-to-method – TrueWill Aug 16 '18 at 16:47
  • 1
    Possible duplicate of [React js onClick can't pass value to method](https://stackoverflow.com/questions/29810914/react-js-onclick-cant-pass-value-to-method) – TrueWill Aug 16 '18 at 16:50

1 Answers1

1

You are mixing things. There are two cases for your situation and you are trying to use them both.

Binding to this

When do you need you bind your function to this? If you are calling your function in callback like your button (one of the cases of course) and you need to use this in this function then you need to bind it. If you don't use this then there is no need to bind it either.

sayHi() {
    console.log("hi");
  };

  render() {
    return (
      <div>
        <button onClick={this.sayHi}>Console Hi!</button>
      </div>
    );
  }
}

Here, you don't need to bind it, also you can use the function with its reference since there is no argument.

constructor(props) {
    super(props);
    this.state = {
      name: "foo",
    }
    this.sayHi = this.sayHi.bind(this);
  }

  sayHi() {
    console.log(this.state.name);
  };

  render() {
    return (
      <div>
        <button onClick={this.sayHi}>Console Hi!</button>
      </div>
    );
  }
}

Here you are using this in the function, so you need to bind it in the constructor or define it as an arrow function.

Your situation

Now, your situation: You are defining your function as an arrow one, no need to bind it anymore if you will use this there. But you are not using it, then no need to use an arrow function. Also, you need to pass an argument to it. So, you need to find a way to accomplish this.

The first method, use an arrow function for onClick. Since if you don't use a callback here you can't use click.

sayHi(msg) {
    console.log(msg);
  };

  render() {
    return (
      <div>
        <button onClick={() => this.sayHi("hi")}>Console Hi!</button>
      </div>
    );
  }
}

If you use like this.sayHi("hi") then this function is invoked in the first render, not with a click.

You can use .bind here as a second method also.

sayHi(msg) {
    console.log(msg);
  };

  render() {
    return (
      <div>
        <button onClick={this.sayHi.bind(null,"hi")}>Console Hi!</button>
      </div>
    );
  }
}

See, we use bind but did not use this since we don't need it. We are not using this in our sayHi function.

devserkan
  • 16,870
  • 4
  • 31
  • 47