Pawel Pawel - 3 years ago 216
Javascript Question

What is the reason that function is not passed to a Button

I'm aware of JavaScript's scopes but probably I don't understand them fully because this code doesn't work.

This code uses React and Relay Modern frameworks.

There are 2 buttons, first one inside

which is passed into Relay Modern
and second one afterwards (see function
). The second one is working, first one doesn't execute the
(This is simplified version of actual code)

class Candidates extends Component {
static propTypes = {
viewer: PropTypes.object

constructor (props) {
this.clickTest = this.clickTest.bind(this)

clickTest () {
console.log('click works')

queryRender ({error, props}) {
if (error) {
return <pre>{error.message}</pre>
} else if (props) {
return (
<Button onClick={this.clickTest}>this DOESN'T work</Button>
return <Loader active>Loading...</Loader>

render () {
return (
<Button onClick={this.clickTest}>this works</Button>

variable is defined, I just didn't include it in that excerpt.

When I substitue first button's onClick function with an anonymous one

<Button onClick={() => this.clickTest()}>this DOESN'T work</Button>

then I get such error: Uncaught TypeError: _this2.clickTest is not a function

Can anyone explain to me why this code behaves the way it does?

Answer Source

In javascript, the meaning of this isn't determined when a function is created, but rather when it is invoked. When QueryRenderer invokes your queryRender function, it doesn't know that it needs to invoke it in the context of your class, so this will not be referring to what you think it's referring to.

You'll either need to bind your queryRender function, much like you're doing with your clicktest function in the constructor, or you'll need to redesign queryRender so it doesn't need a reference to this.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download