scripton
scripton

Reputation: 246

ReactJs update parent after ComponentDidMount from child class

I have a parent class and a child class. The child class will perform an initial load operation based on a property passed from the parent. The parent class will access that data using a static method from the child. In essence, I'm trying to use the child class as a service. The code below illustrates the scenario (note that it's just pseudo code).

var Parent = React.createClass({

 componentDidMount: function() {
    console.log("parent component was mounted");
 },

  render: function() {
    return (
      <div>
        <Child param={this.props.param} />
        <p>Child.fetch('key')</p>
      </div>
    );
  }
});

var Child = React.createClass({
    getInitialState: function() {
        return {
            data: {}
        };
    },

    componentDidMount: function() {
        console.log("child component was mounted");

        $.ajax({
          url: "server/api.php",
        data: {
         param: param
        }
        }).done(function(response) {
          this.setState({data: response});
        }.bind(this));
    },

    statics: {
        get: function(key) {
            console.log('get requested for key: ' + key);

            var value = null; // default value

            if(this.data == null) { return value; }

            //get the value from the data based on the key

            return value;
        }
    },        

  render: function() {
    return (
      <h2>{this.props.param}</h2>
    );
  }
});

The problem here is that the parent's render function does not update after the data was loaded from the child class. The order of the console.log results is:

  1. Parent render: get requested for key: key
  2. parent component was mounted
  3. child component was mounted
  4. => should trigger an update to re-render the parent

I'm not sure if its possible to trigger the parent's render function only once after the child component has been loaded. I'm guessing its not, so triggering an update for the parent's render method would suffice. Any suggestions, improvements are welcome as this is fairly new to me.

Upvotes: 1

Views: 3964

Answers (1)

nbermudezs
nbermudezs

Reputation: 2844

You should add a callback prop to your Child component that the child can trigger once the data has been loaded.

On the Parent side you just need to call this.forceUpdate().

What you are experiencing is expected since the lifecycle of your Child component is different than the one for your Parent class.

Still, you might need to analyze the possibility to move your load logic into the Parent and delegate the rendering of parts of the response to each child. This will also help performance since only one HTTP request will be needed to load all the data.

** Code **

var Parent = React.createClass({

 componentDidMount: function() {
    console.log("parent component was mounted");
 },

  render: function() {
    return (
      <div>
        <Child param={this.props.param} onDataLoaded={this.forceUpdate} />
        <p>Child.fetch('key')</p>
      </div>
    );
  }
});

var Child = React.createClass({
    getInitialState: function() {
        return {
            data: {}
        };
    },

    componentDidMount: function() {
        console.log("child component was mounted");

        $.ajax({
          url: "server/api.php",
        data: {
         param: param
        }
        }).done(function(response) {
          if (typeof this.onDataLoaded === 'function')
            this.onDataLoaded();
          this.setState({data: response});
        }.bind(this));
    },

    statics: {
        get: function(key) {
            console.log('get requested for key: ' + key);

            var value = null; // default value

            if(this.data == null) { return value; }

            //get the value from the data based on the key

            return value;
        }
    },        

  render: function() {
    return (
      <h2>{this.props.param}</h2>
    );
  }
});

Upvotes: 1

Related Questions