1

I know how to get a parent function to run if you trigger it on a onClick event (or similar), but I want to trigger it on ajax success. So pretty much this constallation:

var parent = React.createClass({
    someFunction: function(){
        console.log("Parent function triggered");
    },
    render: function(){
        return (
            <Child callback={this.someFunction} />
        );
    }
});

var child = React.createClass({
    getInitialState: function(){
        return { data: "Wat" };
    },
    componentDidMount: function(){
        $.ajax({
            url: "some_url",
            method: 'POST',
            data: this.state.data,
            success: function(response){
                this.props.callback; // This is what I would like to do
            },
            error: function(){
                console.log("Couldn't do it cap'n");
            }
        });
    },
    render: function(){
        return(
            <div>Hello!</div>
        );  
    }
});

I could do it by triggering an event, but surely it should be possible to do it when I have access to the function. The function is also passed down correctly, and I can see it as a function if I do a console.log(this.props.callback);

Dennis
  • 909
  • 4
  • 13
  • 30
  • 1
    What you have done is pretty much correct. You just need to execute that function in this way - this.props.callback(). Change the function's this keyword, or simply declare var that = this, and call that.props.callback() – booleanhunter Oct 07 '15 at 14:49

1 Answers1

5

You should use Function.prototype.bind to change the function's this keyword:

success: function(response){
  this.props.callback(); // This will work
}.bind(this),

Originally, the this keyword inside the anonymous function you're passing as the success option to the ajax method is not the same this it's outside it.

That happens because of Javascript's lexical scope, and you can change this behavior by overriding what the this keyword will be when the function is called.


Another option is to use a helper variable, e.g:

componentDidMount: function() {
  var self = this;
  $.ajax({
    /* (...) */
    success: function(response) {
      self.props.callback(); // this will work as well
    },
    /* (...) */
  });
}

One more option would be Kevin B's suggestion, to use the jQuery's AJAX context option:

componentDidMount: function() {
  $.ajax({
    /* (...) */
    context: this,
    success: function(response) {
      this.props.callback(); // this will work as well
    },
    /* (...) */
  });
}

And a last option, since you're using React, you're probably transpiling your code through Babel, so, you can take advantage of the ES6's arrow functions, that will automatically lexically the this binding:

success: (response) => {
  this.props.callback(); // This will work too
},
Community
  • 1
  • 1
Buzinas
  • 11,597
  • 2
  • 36
  • 58