0

I have the following code:

class App extends Component {

  constructor(){
    super()
    //this.buttonOneClick = this.buttonOneClick.bind(this);
  }

  buttonOneClick() {
    const { setTestData } = this.props;

    setTestData("test");
  }

  render() {
    const { testData } = this.props;
    return (
      <div className="App">
        <h1>Test App</h1>
        <div>{testData}</div>
        <button onClick={this.buttonOneClick}>Test</button>
      </div>
    );
  }
}

The component App is exported with react-redux's connect method to map the setTestData-function to the props (thats where setTestData is coming from).

When I set the buttonOneClick() handler without biding the component context to it (see the outcommented line in my code in constructor()) I get the following error:

Cannot read property 'props' of undefined

I understand that props wouldn't be defined since the handler is executed in the global context which doesn't know about props but how I understand the error it implies that this itself is not defined which doesn't make sense to me. Why is this the case? Shouldn't this always be defined in any execution context?

Thanks in advance

Benjamin
  • 1,067
  • 20
  • 30

2 Answers2

1

Shouldn't this always be defined in any execution context?

No.

There is no implicit this value in strict mode.

"use strict";

function example() {
    alert(this);
}

example();
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • IMHO it worth mentioning that class bodies enforce strict mode. – Yury Tarabanko Jun 19 '18 at 10:02
  • Good to know. I'll read more about strict mode now (do I get it right that ´this´ is only undefined in strict mode as long as it would refer to the global context?) – Benjamin Jun 19 '18 at 10:20
-1

We’re getting an error because this is not defined when onClick calls our buttonOneClick() function.

Usually, you would fix this by binding this to the buttonOneClick function so it always stays the same. So we have to bind that in the constructor.

this.buttonOneClick = this.buttonOneClick.bind(this);

Possible work-around if you don't want to use the binding and all is to use the es2015 javascript arrow functions

buttonOneClick = () => console.log(this.props);

An arrow function does not have its own this so it will use this off its context, which is our Component. This is called Lexical Scoping